Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions
@@ -0,0 +1,370 @@
/*
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 _WAFE_H_
#define _WAFE_H_
/*
** Winamp frontend/plug-in control API documentation v1.0.
** By Justin Frankel.
** Copyright (C) 1997-1999, Nullsoft Inc.
** Last updated: JAN.8.1999.
**
** Introduction
** -----------------------
** This file describes a means to easily communicate to Winamp
** via the classic Win32 Message API.
**
** These definitions/code assume C/C++. Porting to VB/Delphi shouldn't
** be too hard.
**
** First, you find the HWND of the Winamp main window. From a plug-in
** you can easily extract this from the plug-in structure (hMainWindow,
** hwndParent, whatever). For external apps, use:
**
** HWND hwnd_winamp = FindWindow("Winamp v1.x",NULL);
**
** (note: I know, we're in Winamp 2.x, but it's 1.x for compatibility)
**
** Once you have the hwnd_winamp, it's a good idea to check the version
** number. To do this, you send a WM_WA_IPC message to hwnd_winamp.
** Note that WM_WA_IPC is defined as Win32's WM_USER.
**
** Note that sometimes you might want to use PostMessage instead of
** SendMessage.
*/
#define WM_WA_IPC WM_USER
/**************************************************************************/
#define IPC_GETVERSION 0
/*
** int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
**
** Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0
** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
**
** The basic format for sending messages to Winamp is:
** int result=SendMessage(hwnd_winamp,WM_WA_IPC,command_data,command);
** (for the version check, command_data is 0).
*/
#define IPC_DELETE 101
/*
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
**
** You can use IPC_DELETE to clear Winamp's internal playlist.
*/
#define IPC_STARTPLAY 102
/*
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
**
** Using IPC_STARTPLAY is like hitting 'Play' in Winamp, mostly.
*/
#define IPC_ISPLAYING 104
/*
** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
**
** IPC_ISPLAYING returns the status of playback.
** If it returns 1, it is playing. if it returns 3, it is paused,
** if it returns 0, it is not playing.
*/
#define IPC_GETOUTPUTTIME 105
/*
** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
**
** IPC_GETOUTPUTTIME returns the position in milliseconds of the
** current song (mode = 0), or the song length, in seconds (mode = 1).
** Returns -1 if not playing or error.
*/
#define IPC_JUMPTOTIME 106
/* (requires Winamp 1.60+)
** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
** IPC_JUMPTOTIME sets the position in milliseconds of the
** current song (approximately).
** Returns -1 if not playing, 1 on eof, or 0 if successful
*/
#define IPC_WRITEPLAYLIST 120
/* (requires Winamp 1.666+)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
**
** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u,
** and returns the current playlist position.
** Kinda obsoleted by some of the 2.x new stuff, but still good for when
** using a front-end (instead of a plug-in)
*/
#define IPC_SETPLAYLISTPOS 121
/* (requires Winamp 2.0+)
** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
**
** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
*/
#define IPC_SETVOLUME 122
/* (requires Winamp 2.0+)
** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
**
** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
*/
#define IPC_SETPANNING 123
/* (requires Winamp 2.0+)
** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
**
** IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)).
*/
#define IPC_GETLISTLENGTH 124
/* (requires Winamp 2.0+)
** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
**
** IPC_GETLISTLENGTH returns the length of the current playlist, in
** tracks.
*/
#define IPC_SETSKIN 200
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
**
** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
** can be the name of a skin, a skin .zip file, with or without path.
** If path isn't specified, the default search path is the winamp skins
** directory.
*/
#define IPC_GETSKIN 201
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
**
** IPC_GETSKIN puts the directory where skin bitmaps can be found
** into skinname_buffer.
** skinname_buffer must be MAX_PATH characters in length.
** When using a .zip'd skin file, it'll return a temporary directory
** where the ZIP was decompressed.
*/
#define IPC_EXECPLUG 202
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
**
** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
** the format of this string can be:
** "vis_whatever.dll"
** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
** "C:\\dir\\vis_whatever.dll,1"
*/
#define IPC_GETPLAYLISTFILE 211
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
**
** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
** returns a pointer to it. returns NULL on error.
*/
#define IPC_GETPLAYLISTTITLE 212
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
**
** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
** returns a pointer to it. returns NULL on error.
*/
#define IPC_GETLISTPOS 125
/* (requires Winamp 2.05+)
** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
**
** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
** only faster since it doesn't have to write out the list. Heh, silly me.
*/
#define IPC_GETINFO 126
/* (requires Winamp 2.05+)
** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
**
** IPC_GETINFO returns info about the current playing song. The value
** it returns depends on the value of 'mode'.
** Mode Meaning
** ------------------
** 0 Samplerate (i.e. 44100)
** 1 Bitrate (i.e. 128)
** 2 Channels (i.e. 2)
*/
#define IPC_GETEQDATA 127
/* (requires Winamp 2.05+)
** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
**
** IPC_GETEQDATA queries the status of the EQ.
** The value returned depends on what 'pos' is set to:
** Value Meaning
** ------------------
** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
** 10 The preamp value. 0-63 (+20db - -20db)
** 11 Enabled. zero if disabled, nonzero if enabled.
** 12 Autoload. zero if disabled, nonzero if enabled.
*/
#define IPC_SETEQDATA 128
/* (requires Winamp 2.05+)
** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
**
** IPC_SETEQDATA sets the value of the last position retrieved
** by IPC_GETEQDATA.
*/
/**************************************************************************/
/*
** Some API calls tend to require that you send data via WM_COPYDATA
** instead of WM_USER. Such as IPC_PLAYFILE:
*/
#define IPC_PLAYFILE 100
/*
** COPYDATASTRUCT cds;
** cds.dwData = IPC_PLAYFILE;
** cds.lpData = (void *) "file.mp3";
** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
**
** This will play the file "file.mp3".
**
*/
#define IPC_CHDIR 103
/*
** COPYDATASTRUCT cds;
** cds.dwData = IPC_CHDIR;
** cds.lpData = (void *) "c:\\download";
** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
**
** This will make Winamp change to the directory C:\\download
**
*/
/**************************************************************************/
/*
** Finally there are some WM_COMMAND messages that you can use to send
** Winamp misc commands.
**
** To send these, use:
**
** SendMessage(hwnd_winamp, WM_COMMAND,command_name,0);
*/
#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window
#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window
#define WINAMP_VOLUMEUP 40058 // turns the volume up a little
#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little
#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds
#define WINAMP_REW5S 40061 // rewinds 5 seconds
// the following are the five main control buttons, with optionally shift
// or control pressed
// (for the exact functions of each, just try it out)
#define WINAMP_BUTTON1 40044
#define WINAMP_BUTTON2 40045
#define WINAMP_BUTTON3 40046
#define WINAMP_BUTTON4 40047
#define WINAMP_BUTTON5 40048
#define WINAMP_BUTTON1_SHIFT 40144
#define WINAMP_BUTTON2_SHIFT 40145
#define WINAMP_BUTTON3_SHIFT 40146
#define WINAMP_BUTTON4_SHIFT 40147
#define WINAMP_BUTTON5_SHIFT 40148
#define WINAMP_BUTTON1_CTRL 40154
#define WINAMP_BUTTON2_CTRL 40155
#define WINAMP_BUTTON3_CTRL 40156
#define WINAMP_BUTTON4_CTRL 40157
#define WINAMP_BUTTON5_CTRL 40158
#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box
#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences
#define WINAMP_OPTIONS_AOT 40019 // toggles always on top
#define WINAMP_HELP_ABOUT 40041 // pops up the about box :)
/*
** EOF.. Enjoy.
*/
#endif
@@ -0,0 +1,24 @@
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.
@@ -0,0 +1,69 @@
#include "timing.h"
#ifdef TIMING
#ifndef __alpha
#include <stdio.h>
static struct {
unsigned int st_time[2];
unsigned int cycles;
unsigned int calls;
} timingInfo[64];
static int timingEnters;
static void rdtsc(unsigned int t[2])
{
__asm
{
mov esi, t
_emit 0xf
_emit 0x31
mov [esi], eax
mov [esi+4], edx
}
}
void _timingInit(void)
{
memset(timingInfo,0,sizeof(timingInfo));
}
void _timingEnter(int which)
{
// if (!timingEnters++) __asm cli
rdtsc(timingInfo[which].st_time);
}
void _timingLeave(int which)
{
unsigned int t[2];
rdtsc(t);
// if (!--timingEnters) __asm sti
if (t[1]==timingInfo[which].st_time[1])
{
timingInfo[which].cycles += t[0]-timingInfo[which].st_time[0];
}
else
{
timingInfo[which].cycles += t[0]+(0xffffffff-timingInfo[which].st_time[0]);
}
timingInfo[which].calls++;
}
void _timingPrint(void)
{
int x;
FILE *fp = fopen("C:\\timings.txt","wt");
for (x = 0; x < sizeof(timingInfo)/sizeof(timingInfo[0]); x ++)
{
if (timingInfo[x].calls)
fprintf(fp,"%d: %d calls, %d clocks/call\n",x,timingInfo[x].calls,timingInfo[x].cycles/timingInfo[x].calls);
}
timingInit();
fclose(fp);
}
#endif
#endif
@@ -0,0 +1,32 @@
#ifndef _TIMING_H_
#define _TIMING_H_
//#define TIMING
#if defined(TIMING) && !defined(__alpha)
#ifdef __cplusplus
extern "C" {
#endif
void _timingInit(void);
void _timingPrint(void);
void _timingEnter(int);
void _timingLeave(int);
#ifdef __cplusplus
}
#endif
#define timingPrint() _timingPrint()
#define timingInit() _timingInit()
#define timingLeave(x) _timingLeave(x)
#define timingEnter(x) _timingEnter(x)
#else
#define timingPrint()
#define timingInit()
#define timingLeave(x)
#define timingEnter(x)
#endif
#endif
+76
View File
@@ -0,0 +1,76 @@
/*
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.
*/
// notes:
// any window that remains in foreground should optimally pass
// keystrokes to the parent (winamp's) window, so that the user
// can still control it. unless escape is hit, or some option
// key specific to the vis is hit. As for storing configuration,
// Configuration data should be stored in <dll directory>\plugin.ini
// Look at the example plugin for a framework.
// ints are 32 bits, and structure members are aligned on the default 8 byte boundaries
// tested with VC++ 4.2 and 5.0
typedef struct winampVisModule {
char *description; // description of module
HWND hwndParent; // parent window (filled in by calling app)
HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app)
int sRate; // sample rate (filled in by calling app)
int nCh; // number of channels (filled in...)
int latencyMs; // latency from call of RenderFrame to actual drawing
// (calling app looks at this value when getting data)
int delayMs; // delay between calls in ms
// the data is filled in according to the respective Nch entry
int spectrumNch;
int waveformNch;
unsigned char spectrumData[2][576];
unsigned char waveformData[2][576];
void (*Config)(struct winampVisModule *this_mod); // configuration dialog
int (*Init)(struct winampVisModule *this_mod); // 0 on success, creates window, etc
int (*Render)(struct winampVisModule *this_mod); // returns 0 if successful, 1 if vis should end
void (*Quit)(struct winampVisModule *this_mod); // call when done
void *userData; // user data, optional
} winampVisModule;
typedef struct {
int version; // VID_HDRVER
char *description; // description of library
winampVisModule* (*getModule)(int);
} winampVisHeader;
// exported symbols
typedef winampVisHeader* (*winampVisGetHeaderType)();
// version of current module (0x101 == 1.01)
#define VIS_HDRVER 0x101
+96
View File
@@ -0,0 +1,96 @@
/*
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 _APE_H_
#define _APE_H_
//extended APE stuff
// to use this, you should have:
// APEinfo *g_extinfo;
// void __declspec(dllexport) AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
// {
// g_extinfo = ptr;
// }
typedef void *VM_CONTEXT;
typedef void *VM_CODEHANDLE;
typedef struct
{
int ver; // ver=1 to start
double *global_registers; // 100 of these
// lineblendmode: 0xbbccdd
// bb is line width (minimum 1)
// dd is blend mode:
// 0=replace
// 1=add
// 2=max
// 3=avg
// 4=subtractive (1-2)
// 5=subtractive (2-1)
// 6=multiplicative
// 7=adjustable (cc=blend ratio)
// 8=xor
// 9=minimum
int *lineblendmode;
//evallib interface
VM_CONTEXT (*allocVM)(); // return a handle
void (*freeVM)(VM_CONTEXT); // free when done with a VM and ALL of its code have been freed, as well
// you should only use these when no code handles are around (i.e. it's okay to use these before
// compiling code, or right before you are going to recompile your code.
void (*resetVM)(VM_CONTEXT);
double * (*regVMvariable)(VM_CONTEXT, const char *name);
// compile code to a handle
VM_CODEHANDLE (*compileVMcode)(VM_CONTEXT, char *code);
// execute code from a handle
void (*executeCode)(VM_CODEHANDLE, char visdata[2][2][576]);
// free a code block
void (*freeCode)(VM_CODEHANDLE);
// requires ver >= 2
void (*doscripthelp)(HWND hwndDlg,char *mytext); // mytext can be NULL for no custom page
/// requires ver >= 3
void *(*getNbuffer)(int w, int h, int n, int do_alloc); // do_alloc should be 0 if you dont want it to allocate if empty
// w and h should be the current width and height
// n should be 0-7
} APEinfo;
#endif//_APE_H_
@@ -0,0 +1,80 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOG DISCARDABLE 0, 0, 137, 137
STYLE WS_CHILD
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Enable Tutorial Effect",IDC_CHECK1,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,25,86,84,10
CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,39,29,
53,49
LTEXT "Color",IDC_STATIC,56,14,17,8
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
@@ -0,0 +1,110 @@
// AVS APE (Plug-in Effect) header
// base class to derive from
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, 0 if framebuffer 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; }
};
// if you want to support SMP rendering, you can derive from this class instead,
// and expose the creator via: _AVS_APE_RetrFuncEXT2
// (in general, exposing both for compatibility is a good idea)
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
};
// lovely helper functions for blending
static unsigned int __inline BLEND(unsigned int a, unsigned int b)
{
register unsigned int r,t;
r=(a&255)+((b)&255);
t=min(r,255);
r=((a>>8)&255)+((b>>8)&255);
t|=min(r,255)<<8;
r=((a>>16)&255)+((b>>16)&255);
return t|min(r,255)<<16;
}
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)));
}
//extended APE stuff
// to use this, you should have:
// APEinfo *g_extinfo;
// void __declspec(dllexport) AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
// {
// g_extinfo = ptr;
// }
typedef void *VM_CONTEXT;
typedef void *VM_CODEHANDLE;
typedef struct
{
int ver; // ver=1 to start
double *global_registers; // 100 of these
// lineblendmode: 0xbbccdd
// bb is line width (minimum 1)
// dd is blend mode:
// 0=replace
// 1=add
// 2=max
// 3=avg
// 4=subtractive (1-2)
// 5=subtractive (2-1)
// 6=multiplicative
// 7=adjustable (cc=blend ratio)
// 8=xor
// 9=minimum
int *lineblendmode;
//evallib interface
VM_CONTEXT (*allocVM)(); // return a handle
void (*freeVM)(VM_CONTEXT); // free when done with a VM and ALL of its code have been freed, as well
// you should only use these when no code handles are around (i.e. it's okay to use these before
// compiling code, or right before you are going to recompile your code.
void (*resetVM)(VM_CONTEXT);
double * (*regVMvariable)(VM_CONTEXT, char *name);
// compile code to a handle
VM_CODEHANDLE (*compileVMcode)(VM_CONTEXT, char *code);
// execute code from a handle
void (*executeCode)(VM_CODEHANDLE, char visdata[2][2][576]);
// free a code block
void (*freeCode)(VM_CODEHANDLE);
// requires ver >= 2
void (*doscripthelp)(HWND hwndDlg,char *mytext); // mytext can be NULL for no custom page
/// requires ver >= 3
void *(*getNbuffer)(int w, int h, int n, int do_alloc); // do_alloc should be 0 if you dont want it to allocate if empty
// w and h should be the current width and height
// n should be 0-7
} APEinfo;
@@ -0,0 +1,294 @@
/**
Example Winamp AVS plug-in
Copyright (c) 2000, Nullsoft Inc.
Hello, welcome to the first Advanced Visualization
Studio tutorial!
The hope is that together, we can learn to utilize
AVS's powerful features: Namely direct access to the
frame buffer, EZ beat detection, and the ability to
stack plug-ins written by other developers for an
infinite array of possible effects.
I hereby present:
Tutorial 0: BOX-
Simplicity at its finest. Displays a rectangle on
screen on every beat. Oh, and you can change its color
too... Check avstut00.avs for a demonstration of a
spinning rectangle's power!
good luck and have fun!
**/
#include <windows.h>
#include "resource.h"
#include "avs_ape.h"
#define MOD_NAME "Tutorials / BOX v1.0"
#define UNIQUEIDSTRING "Nullsoft Tut0: BOX"
// extended APE api support
APEinfo *g_extinfo;
extern "C"
{
void __declspec(dllexport) _AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
{
g_extinfo = ptr;
}
}
class C_THISCLASS : public C_RBASE
{
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 HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual char *get_desc();
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int enabled; // toggles plug-in on and off
int color; // color of rectangle
};
// global configuration dialog pointer
static C_THISCLASS *g_ConfigThis;
// global DLL instance pointer (not needed in this example, but could be useful)
static HINSTANCE g_hDllInstance;
// this is where we deal with the configuration screen
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (g_ConfigThis->enabled)
{
CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
}
return 1;
case WM_DRAWITEM:
DRAWITEMSTRUCT *di;
di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL)
{
int w;
int color;
w=di->rcItem.right-di->rcItem.left;
color=g_ConfigThis->color;
color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
// paint nifty color button
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={BS_SOLID,color,0};
hBrush = CreateBrushIndirect(&lb);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
}
return 0;
case WM_COMMAND:
// see if enable checkbox is checked
if (LOWORD(wParam) == IDC_CHECK1)
{
g_ConfigThis->enabled= (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0);
}
// is colorbox is selected?
if (LOWORD(wParam) == IDC_DEFCOL)
{
static COLORREF custcolors[16];
int *a;
CHOOSECOLOR cs;
a=&g_ConfigThis->color;
cs.lStructSize = sizeof(cs);
cs.hwndOwner = hwndDlg;
cs.hInstance = 0;
cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
cs.lpCustColors = custcolors;
cs.Flags = CC_RGBINIT|CC_FULLOPEN;
// go to windows color selection screen
if (ChooseColor(&cs))
{
*a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
}
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
return 0;
}
return 0;
}
// set up default configuration
C_THISCLASS::C_THISCLASS()
{
//set initial color
color=RGB(255,0,0);
enabled=1;
}
// virtual destructor
C_THISCLASS::~C_THISCLASS()
{
}
// RENDER FUNCTION:
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the-*/ width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int halfw;
int halfh;
// is this effect on?
if (!enabled)
{
return 0;
}
// did we just hit a beat?
if(isBeat)
{
// draw our magic box
halfw=w/2;
halfh=h/2;
framebuffer+=(((halfh/2)*w)+ (halfw/2));
for(int j=0;j<halfh;j++)
{
for(int i=0;i<halfw;i++)
{
framebuffer[i]=color;
}
framebuffer+=w;
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return CreateDialog(hInstance,MAKEINTRESOURCE(IDD_CONFIG),hwndParent,g_DlgProc);
}
char *C_THISCLASS::get_desc(void)
{
return MOD_NAME;
}
// load_/save_config are called when saving and loading presets (.avs files)
#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) // read configuration of max length "len" from data.
{
int pos=0;
// always ensure there is data to be loaded
if (len-pos >= 4)
{
// load activation toggle
enabled=GET_INT();
pos+=4;
}
if (len-pos >= 4)
{
// load the box color
color=GET_INT();
pos+=4;
}
}
// write configuration to data, return length. config data should not exceed 64k.
#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
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled);
pos+=4;
PUT_INT(color);
pos+=4;
return pos;
}
// export stuff
C_RBASE *R_RetrFunc(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc)
{
strcpy(desc,MOD_NAME);
return NULL;
}
return (C_RBASE *) new C_THISCLASS();
}
extern "C"
{
__declspec (dllexport) int _AVS_APE_RetrFunc(HINSTANCE hDllInstance, char **info, int *create) // return 0 on failure
{
g_hDllInstance=hDllInstance;
*info=UNIQUEIDSTRING;
*create=(int)(void*)R_RetrFunc;
return 1;
}
};
/**
Final Thoughts:
Alright! Hopefully you guys can take the next step
and display more than just a colored rectangle ;) The
exciting thing is, each time you write an AVS plug-in,
you exponentially increase AVS's potential, unlocking
the possibility of an effect you never expected. Good
luck, I hope this has helped!
See you next time!
**/
@@ -0,0 +1,120 @@
# Microsoft Developer Studio Project File - Name="avstut00" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=avstut00 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "avstut00.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "avstut00.mak" CFG="avstut00 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "avstut00 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "avstut00 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "avstut00 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"c:/program files/winamp/plugins/avs/avstut00.ape"
!ELSEIF "$(CFG)" == "avstut00 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /WX /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 msvcrt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /machine:I386 /nodefaultlib /out:"c:/program files/winamp/plugins/avs/avstut00.ape" /pdbtype:sept
# SUBTRACT LINK32 /debug
!ENDIF
# Begin Target
# Name "avstut00 - Win32 Release"
# Name "avstut00 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\ape.rc
# End Source File
# Begin Source File
SOURCE=.\avstut00.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\avs_ape.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "avstut00"=".\avstut00.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
@@ -0,0 +1,19 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ape.rc
//
#define IDD_CONFIG 109
#define IDC_CHECK1 1000
#define IDC_DEFCOL 1036
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,235 @@
/*
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.
*/
#include <windows.h>
#include "../ns-eel2/ns-eel-int.h"
#include "../ns-eel2/ns-eel-addfuncs.h"
#include "avs_eelif.h"
char last_error_string[1024];
int g_log_errors;
CRITICAL_SECTION g_eval_cs;
static char *g_evallib_visdata;
/////////////////////// begin AVS specific script functions
static double NSEEL_CGEN_CALL getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
{
int x;
int accum=0;
if (ch && ch != 1 && ch != 2) return 0.0;
if (bw < 1) bw=1;
bc-=bw/2;
if (bc < 0)
{
bw+=bc;
bc=0;
}
if (bc > 575) bc=575;
if (bc+bw > 576) bw=576-bc;
if (!ch)
{
for (x = 0; x < bw; x ++)
{
accum+=(visdata[bc]^xorv)-xorv;
accum+=(visdata[bc+576]^xorv)-xorv;
bc++;
}
return (double)accum / ((double)bw*255.0);
}
else
{
if (ch == 2) visdata+=576;
for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
return (double)accum / ((double)bw*127.5);
}
}
static double NSEEL_CGEN_CALL getspec_(void *_this, double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),0)*0.5;
}
static double NSEEL_CGEN_CALL getosc_(void *_this, double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata+576*2,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),128);
}
static double NSEEL_CGEN_CALL gettime_(void *_this, double *sc)
{
int ispos;
if ((ispos=(*sc > -1.001 && *sc < -0.999)) || (*sc > -2.001 && *sc < -1.999))
{
int pos=0;
extern HWND hwnd_WinampParent;
if (IsWindow(hwnd_WinampParent))
{
if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!ispos,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos)) pos=0;
}
if (!ispos) return (double)pos;
return pos / 1000.0;
}
return GetTickCount()/1000.0 - *sc;
}
static double NSEEL_CGEN_CALL setmousepos_(void *_this, double *x, double *y)
{
//fucko: implement me
return 0.0;
}
extern double DDraw_translatePoint(POINT p, int isY);
static double NSEEL_CGEN_CALL getmouse_(void *_this, double *which)
{
int w=(int)(*which+0.5);
if (w > 5)
return (GetAsyncKeyState(w)&0x8000)?1.0:0.0;
if (w == 1 || w == 2)
{
POINT p;
GetCursorPos(&p);
return DDraw_translatePoint(p,w==2);
}
if (w == 3) return (GetAsyncKeyState(MK_LBUTTON)&0x8000)?1.0:0.0;
if (w == 4) return (GetAsyncKeyState(MK_RBUTTON)&0x8000)?1.0:0.0;
if (w == 5) return (GetAsyncKeyState(MK_MBUTTON)&0x8000)?1.0:0.0;
return 0.0;
}
/////////////////////// end AVS specific script functions
void NSEEL_HOSTSTUB_EnterMutex()
{
EnterCriticalSection(&g_eval_cs);
}
void NSEEL_HOSTSTUB_LeaveMutex()
{
LeaveCriticalSection(&g_eval_cs);
}
void AVS_EEL_IF_init()
{
InitializeCriticalSection(&g_eval_cs);
NSEEL_init();
// todo: check to see that parameter orders are correct
NSEEL_addfunctionex("getosc",3,(char *)_asm_generic3parm_retd,(char *)_asm_generic3parm_retd_end-(char *)_asm_generic3parm_retd,NSEEL_PProc_THIS,(void*)getosc_);
NSEEL_addfunctionex("getspec",3,(char *)_asm_generic3parm_retd,(char *)_asm_generic3parm_retd_end-(char *)_asm_generic3parm_retd,NSEEL_PProc_THIS,(void*)getspec_);
NSEEL_addfunctionex("gettime",1,(char *)_asm_generic1parm_retd,(char *)_asm_generic1parm_retd_end-(char *)_asm_generic1parm_retd,NSEEL_PProc_THIS,(void*)gettime_);
NSEEL_addfunctionex("getkbmouse",1,(char *)_asm_generic1parm_retd,(char *)_asm_generic1parm_retd_end-(char *)_asm_generic1parm_retd,NSEEL_PProc_THIS,(void*)getmouse_);
NSEEL_addfunctionex("setmousepos",2,(char *)_asm_generic2parm_retd,(char *)_asm_generic2parm_retd_end-(char *)_asm_generic2parm_retd,NSEEL_PProc_THIS,(void*)setmousepos_);
}
void AVS_EEL_IF_quit()
{
DeleteCriticalSection(&g_eval_cs);
NSEEL_quit();
}
static void movestringover(char *str, int amount)
{
char tmp[1024+8];
int l=(int)strlen(str);
l=min(1024-amount-1,l);
memcpy(tmp,str,l+1);
while (l >= 0 && tmp[l]!='\n') l--;
l++;
tmp[l]=0;//ensure we null terminate
memcpy(str+amount,tmp,l+1);
}
NSEEL_CODEHANDLE AVS_EEL_IF_Compile(void *context, char *code)
{
NSEEL_CODEHANDLE ret;
EnterCriticalSection(&g_eval_cs);
ret=NSEEL_code_compile((NSEEL_VMCTX)context,code,0);
if (!ret)
{
if (g_log_errors)
{
char *expr = NSEEL_code_getcodeerror((NSEEL_VMCTX)context);
if (expr)
{
int l=strlen(expr);
if (l > 512) l=512;
movestringover(last_error_string,l+2);
memcpy(last_error_string,expr,l);
last_error_string[l]='\r';
last_error_string[l+1]='\n';
}
}
}
LeaveCriticalSection(&g_eval_cs);
return ret;
}
void AVS_EEL_IF_Execute(NSEEL_CODEHANDLE handle, char visdata[2][2][576])
{
if (handle)
{
EnterCriticalSection(&g_eval_cs);
g_evallib_visdata=(char*)visdata;
NSEEL_code_execute((NSEEL_CODEHANDLE)handle);
g_evallib_visdata=NULL;
LeaveCriticalSection(&g_eval_cs);
}
}
void AVS_EEL_IF_resetvars(NSEEL_VMCTX ctx)
{
NSEEL_VM_freeRAM(ctx);
NSEEL_VM_remove_all_nonreg_vars(ctx);
}
@@ -0,0 +1,59 @@
/*
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 _AVS_EEL_IF_H_
#define _AVS_EEL_IF_H_
#include "../ns-eel2/ns-eel.h"
void AVS_EEL_IF_init();
void AVS_EEL_IF_quit();
NSEEL_CODEHANDLE AVS_EEL_IF_Compile(void *ctx, char *code);
void AVS_EEL_IF_Execute(NSEEL_CODEHANDLE handle, char visdata[2][2][576]);
void AVS_EEL_IF_resetvars(NSEEL_VMCTX ctx);
#define AVS_EEL_IF_VM_free(x) NSEEL_VM_free(x)
extern char last_error_string[1024];
extern int g_log_errors;
extern CRITICAL_SECTION g_eval_cs;
// our old-style interface
#define compileCode(exp) AVS_EEL_IF_Compile(AVS_EEL_CONTEXTNAME,(exp))
#define executeCode(x,y) AVS_EEL_IF_Execute(x,y)
#define freeCode(h) NSEEL_code_free(h)
#define resetVars(x) FIXME+++++++++
#define registerVar(x) NSEEL_VM_regvar(AVS_EEL_CONTEXTNAME,(x))
#define clearVars() AVS_EEL_IF_resetvars(AVS_EEL_CONTEXTNAME)
#define AVS_EEL_INITINST() AVS_EEL_CONTEXTNAME=NSEEL_VM_alloc()
#define AVS_EEL_QUITINST() NSEEL_VM_free(AVS_EEL_CONTEXTNAME)
#endif//_AVS_EEL_IF_H_
+711
View File
@@ -0,0 +1,711 @@
/*
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.
*/
#include <windows.h>
#include <commctrl.h>
#include <math.h>
#include <stdio.h>
#include "draw.h"
#include "wnd.h"
#include "r_defs.h"
#include "render.h"
#include "vis.h"
#include "cfgwnd.h"
#include "resource.h"
#include "bpm.h"
#include "../Agave/Language/api_language.h"
int refineBeat(int isBeat);
BOOL TCHistStep(BeatType *t, DWORD _Avg, int *_halfDiscriminated, int *_hdPos, DWORD *_lastTC, DWORD TC, int Type);
void InsertHistStep(BeatType *t, DWORD TC, int Type, int i);
void CalcBPM(void);
BOOL ReadyToLearn(void);
BOOL ReadyToGuess(void);
void doubleBeat(void);
void halfBeat(void);
void ResetAdapt(void);
void SliderStep(int Ctl, int *slide);
void initBpm(void);
extern int g_fakeinit;
int cfg_smartbeat=0;
int cfg_smartbeatsticky=1;
int cfg_smartbeatresetnewsong=1;
int cfg_smartbeatonlysticky=0;
int sticked=0;
int arbVal, skipVal; // Values of arbitrary beat and beat skip
int Bpm, Confidence, Confidence1, Confidence2; // Calculated BPM (realtime), Confidence computation
DWORD lastTC; // Last beat Tick count
DWORD lastTC2; // Last beat tick count 2
BeatType TCHist[8]; // History of last 8 beats
BeatType TCHist2[8]; // History of last 8 beats
int Smoother[8]; // History of last 8 Bpm values, used to smooth changes
int halfDiscriminated[8]; // Discriminated beats table
int halfDiscriminated2[8]; // Discriminated beats table
int hdPos; // Position in discrimination table
int hdPos2; // Position in discrimination table
int smPtr, smSize; // Smoother pointer and size
int TCHistPtr; // Tick count history pointer
int TCHistSize; // Tick count history size
int offIMax; // Max divisor/multiplier used to guess/discriminate beats
int lastBPM; // Last calculated BPM, used by the smoother to detect new entry
int insertionCount; // Remembers how many beats were guessed
DWORD predictionLastTC; // Last tick count of guessed/accepted beat
DWORD Avg; // Average tick count interval between beats
DWORD Avg2; // Average tick count interval between beats
int skipCount; // Beat counter used by beat skipper
int inInc, outInc; // +1/-1, Used by the nifty beatsynced sliders
int inSlide, outSlide; // Positions of sliders
int oldInSlide, oldOutSlide; // Used by timer to detect changes in sliders
int oldsticked; // Used by timer to detect changes in sticked state
char txt[256]; // Contains txt about current BPM and confidence
int halfCount, doubleCount; // Counter used to autodetect if double/half beat needed
int TCUsed; // Remembers how many beats in the history were actually used for computation
int predictionBpm; // Contains BPM actually used to prediction (eliminates Bpm driftings)
int oldDisplayBpm, oldDisplayConfidence; // Detects stuff to redraw
int bestConfidence; // Best confidence we had so far
char lastSongName[256]; // Last song name, used to detect song changes in winamp
HWND winampWnd; // Winamp window
int forceNewBeat; // Force new bpm adoption
int betterConfidenceCount; // Used to decide when to adpot new beat
int topConfidenceCount; // Used to decide when to adpot new beat
int stickyConfidenceCount; // Used to decided when to go sticky
BOOL doResyncBpm=FALSE;
// configuration dialog stuff
BOOL CALLBACK DlgProc_Bpm(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
inInc = 1;
outInc = 1;
inSlide = 0;
outSlide = 0;
oldDisplayBpm=-1;
oldDisplayConfidence=-1;
oldInSlide=-1;
oldOutSlide=-1;
if (cfg_smartbeat) CheckDlgButton(hwndDlg,IDC_BPMADV,BST_CHECKED); else CheckDlgButton(hwndDlg,IDC_BPMSTD,BST_CHECKED);
if (cfg_smartbeatsticky) CheckDlgButton(hwndDlg,IDC_STICKY,BST_CHECKED);
if (cfg_smartbeatresetnewsong) CheckDlgButton(hwndDlg,IDC_NEWRESET,BST_CHECKED); else CheckDlgButton(hwndDlg,IDC_NEWADAPT,BST_CHECKED);
if (cfg_smartbeatonlysticky) CheckDlgButton(hwndDlg,IDC_ONLYSTICKY,BST_CHECKED);
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
if (predictionBpm)
{
ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), sticked ? SW_HIDE : SW_NORMAL);
ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), sticked ? SW_NORMAL : SW_HIDE);
}
else
{
ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), SW_HIDE);
}
/* ShowWindow(GetDlgItem(hwndDlg, IDC_CURBPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_CURCONF), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_BPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_CONFIDENCE), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESET), cfg_smartbeat ? SW_NORMAL : SW_HIDE);*/
SetTimer(hwndDlg, 0, 50, NULL);
return 1;
case WM_TIMER:
{
if (oldInSlide != inSlide) {
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETPOS, TRUE, inSlide); oldInSlide=inSlide; }
if (oldOutSlide != outSlide) {
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETPOS, TRUE, outSlide); oldOutSlide=outSlide; }
if (oldDisplayBpm != predictionBpm || oldsticked != sticked) {
char lBuf[16];
wsprintf(txt, predictionBpm ? "%d%s"/*/%d"*/ : WASABI_API_LNGSTRING_BUF(IDS_LEARNING,lBuf,16), predictionBpm, cfg_smartbeatsticky && sticked ? WASABI_API_LNGSTRING(IDS_GOT_IT) : ""/*, Bpm*/);
SetDlgItemText(hwndDlg, IDC_BPM, txt);
oldDisplayBpm=predictionBpm;
oldsticked=sticked;
if (predictionBpm)
{
ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), sticked ? SW_HIDE : SW_NORMAL);
ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), sticked ? SW_NORMAL : SW_HIDE);
}
else
{
ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), SW_HIDE);
}
}
if (oldDisplayConfidence != Confidence) {
wsprintf(txt, "%d%%"/* (%d%%/%d%% - %d)"*/, Confidence/*, Confidence1, Confidence2, TCUsed*/);
SetDlgItemText(hwndDlg, IDC_CONFIDENCE, txt);
oldDisplayConfidence=Confidence;
}
}
return 0;
case WM_COMMAND:
if ((LOWORD(wParam) == IDC_BPMSTD) ||
(LOWORD(wParam) == IDC_BPMADV) ||
(LOWORD(wParam) == IDC_NEWRESET) ||
(LOWORD(wParam) == IDC_NEWADAPT) ||
(LOWORD(wParam) == IDC_ONLYSTICKY) ||
(LOWORD(wParam) == IDC_STICKY))
{
cfg_smartbeat=IsDlgButtonChecked(hwndDlg,IDC_BPMADV)?1:0;
cfg_smartbeatsticky=IsDlgButtonChecked(hwndDlg,IDC_STICKY)?1:0;
cfg_smartbeatresetnewsong=IsDlgButtonChecked(hwndDlg,IDC_NEWRESET)?1:0;
cfg_smartbeatonlysticky=IsDlgButtonChecked(hwndDlg,IDC_ONLYSTICKY)?1:0;
oldsticked=-1;
/* ShowWindow(GetDlgItem(hwndDlg, IDC_CURBPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_CURCONF), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_BPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_CONFIDENCE), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESET), cfg_smartbeat ? SW_NORMAL : SW_HIDE);*/
}
if (LOWORD(wParam) == IDC_2X)
doubleBeat();
if (LOWORD(wParam) == IDC_DIV2)
halfBeat();
if (LOWORD(wParam) == IDC_RESET)
ResetAdapt();
if (LOWORD(wParam) == IDC_STICK)
{
sticked=1;
stickyConfidenceCount=0;
}
if (LOWORD(wParam) == IDC_UNSTICK)
{
sticked=0;
stickyConfidenceCount=0;
}
return 0;
case WM_DESTROY:
KillTimer(hwndDlg, 0);
return 0;
}
return 0;
}
void initBpm(void)
{
if (g_fakeinit) return;
TCUsed=0;
*txt=0;
betterConfidenceCount=0;
topConfidenceCount=0;
forceNewBeat=0;
hdPos=0;
hdPos2=0;
inSlide=0;
outSlide=0;
oldDisplayBpm=-1;
oldDisplayConfidence=-1;
oldInSlide=0;
oldOutSlide=0;
Bpm = 0;
Avg = 0;
Avg2 = 0;
smPtr = 0;
smSize = 8;
offIMax = 8;
insertionCount = 0;
predictionLastTC = 0;
Confidence = 0;
Confidence1 = 0;
Confidence2 = 0;
halfCount=0;
doubleCount=0;
TCHistSize = 8;
predictionBpm=0;
lastTC=GetTickCount();
stickyConfidenceCount=0;
memset(TCHist, 0, TCHistSize*sizeof(BeatType));
memset(Smoother, 0, smSize*sizeof(int));
memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
memset(halfDiscriminated2, 0, TCHistSize*sizeof(int));
winampWnd = FindWindow("Winamp v1.x", NULL);
*lastSongName=0;
sticked=0;
oldsticked=-1;
}
BOOL songChanged(DWORD TCNow)
{
static DWORD lastCheck=0;
if (TCNow > lastCheck+1000)
{
char songName[256];
lastCheck=TCNow;
GetWindowText(winampWnd, songName, 255);
if (strcmp(songName, lastSongName))
{
strcpy(lastSongName, songName);
return TRUE;
}
}
return FALSE;
}
void ResetAdapt(void)
{
// Reset adaptive learning
*txt=0;
TCUsed=0;
hdPos=0;
Avg = 0;
Confidence=0;
Confidence1=0;
Confidence2=0;
betterConfidenceCount=0;
topConfidenceCount=0;
Bpm = 0;
smPtr = 0;
smSize = 8;
offIMax = 8;
insertionCount = 0;
predictionLastTC = 0;
halfCount=0;
doubleCount=0;
TCHistSize = 8;
predictionBpm=0;
bestConfidence=0;
lastTC=GetTickCount();
sticked=0;
oldsticked=-1;
stickyConfidenceCount=0;
memset(TCHist, 0, TCHistSize*sizeof(BeatType));
memset(TCHist2, 0, TCHistSize*sizeof(BeatType));
memset(Smoother, 0, smSize*sizeof(int));
memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
}
// Insert a beat in history table. May be either real beat or guessed
void InsertHistStep(BeatType *t, DWORD TC, int Type, int i)
{
if (i >= TCHistSize) return;
if (t == TCHist && insertionCount < TCHistSize*2) insertionCount++;
memmove(t+i+1, t+i, sizeof(BeatType)*(TCHistSize-(i+1)));
t[0].TC = TC;
t[0].Type = Type;
}
// Doubles current beat
void doubleBeat(void)
{
int i;
int iv[8];
if (sticked && Bpm > MIN_BPM) return;
for (i=0;i<TCHistSize-1;i++)
iv[i] = TCHist[i].TC - TCHist[i+1].TC;
for (i=1;i<TCHistSize;i++)
TCHist[i].TC = TCHist[i-1].TC-iv[i-1]/2;
Avg /= 2;
Bpm *= 2;
doubleCount=0;
memset(Smoother, 0, smSize*sizeof(int));
memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
//forceNewBeat=1;
}
// Halfs current beat
void halfBeat(void)
{
int i;
int iv[8];
if (sticked && Bpm < MIN_BPM) return;
for (i=0;i<TCHistSize-1;i++)
iv[i] = TCHist[i].TC - TCHist[i+1].TC;
for (i=1;i<TCHistSize;i++)
TCHist[i].TC = TCHist[i-1].TC-iv[i-1]*2;
Avg *= 2;
Bpm /= 2;
halfCount=0;
memset(Smoother, 0, smSize*sizeof(int));
memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
}
// Called whenever isBeat was true in render
BOOL TCHistStep(BeatType *t, DWORD _Avg, int *_halfDiscriminated, int *_hdPos, DWORD *_lastTC, DWORD TC, int Type)
{
int i=0;
int offI;
DWORD thisLen;
BOOL learning = ReadyToLearn();
thisLen = TC-lastTC;
// If this beat is sooner than half the average - 20%, throw it away
if (thisLen < Avg/2 - Avg*0.2)
{
if (learning)
{
if (labs(Avg - (TC - t[1].TC)) < labs(Avg - (t[0].TC - t[1].TC)))
{
/* if (predictionLastTC && t[0].Type == BEAT_GUESSED && Type == BEAT_REAL)
predictionLastTC += (TC - t[0].TC)/2;*/
t[0].TC = TC;
t[0].Type = Type;
return TRUE;
}
}
return FALSE;
}
if (learning)
for (offI=2;offI<offIMax;offI++) // Try to see if this beat is in the middle of our current Bpm, or maybe 1/3, 1/4 etc... to offIMax
if ((float)labs((Avg/offI)-thisLen) < (float)(Avg/offI)*0.2)
{
_halfDiscriminated[(*_hdPos)++]=1; // Should test if offI==2 before doing that, but seems to have better results ? I'll have to investigate this
(*_hdPos)%=8;
return FALSE;
}
// This beat is accepted, so set this discrimination entry to false
_halfDiscriminated[hdPos++]=0;
(*_hdPos)%=8;
// Check if we missed some beats
/*if (learning && thisLen > 1000 || (float)abs(Avg-thisLen) > (float)Avg*0.3)
for (offI=2;offI<offIMax;offI++)
{
if ((float)abs((Avg*offI)-thisLen) < (float)Avg*0.2)
{
for (j=1;j<offI;j++) // Oh yeah we definitly did, add one!
InsertHistStep(TC - (Avg*j), BEAT_GUESSED, offI-1); // beat has been guessed so report it so confidence can be calculated
break;
}
}*/
// Remember this tick count
*_lastTC = TC;
// Insert this beat.
InsertHistStep(t, TC, Type, 0);
return TRUE;
}
// Am i ready to learn ?
BOOL ReadyToLearn(void)
{
int i;
for (i=0;i<TCHistSize;i++)
if (TCHist[i].TC==0) return FALSE;
return TRUE;
}
// Am i ready to guess ?
BOOL ReadyToGuess(void)
{
return insertionCount == TCHistSize*2;
}
void newBpm(int thisBpm)
{
Smoother[smPtr++] = thisBpm;
smPtr %= smSize;
}
int GetBpm(void)
{
int i;
int smN=0;
int smSum=0;
// Calculate smoothed Bpm
for (i=0;i<smSize;i++)
if (Smoother[i] > 0) {
smSum += Smoother[i];
smN++;
}
if (smN) return smSum / smN;
return 0;
}
// Calculate BPM according to beat history
void CalcBPM(void)
{
int i;
int hdCount=0;
int r=0;
int totalTC=0, totalN=0;
float rC, etC;
int v;
double sc=0;
int mx=0;
float et;
int smSum=0, smN=0;
if (!ReadyToLearn())
return;
// First calculate average beat
for (i=0;i<TCHistSize-1;i++)
totalTC += TCHist[i].TC - TCHist[i+1].TC;
Avg = totalTC/(TCHistSize-1);
// Count how many of then are real as opposed to guessed
for (i=0;i<TCHistSize;i++)
if (TCHist[i].Type == BEAT_REAL)
r++;
// Calculate part 1 of confidence
rC = (float)min((float)((float)r / (float)TCHistSize) * 2, 1);
// Calculate typical drift
for (i=0;i<TCHistSize-1;i++)
{
v = TCHist[i].TC - TCHist[i+1].TC;
mx = max(mx, v);
sc += v*v;
}
et = (float)sqrt(sc / (TCHistSize-1) - Avg*Avg);
// Calculate confidence based on typical drift and max derivation
etC = 1 - ((float)et / (float)mx);
// Calculate confidence
Confidence = max(0, (int)(((rC * etC) * 100.0) - 50) * 2);
Confidence1 = (int)(rC * 100);
Confidence2 = (int)(etC * 100);
// Now apply second layer, recalculate average using only beats within range of typical drift
// Also, count how many of them we are keeping
totalTC=0;
for (i=0;i<TCHistSize-1;i++)
{
v += TCHist[i].TC - TCHist[i+1].TC;
if (labs(Avg-v) < et)
{
totalTC += v;
totalN++;
v = 0;
}
else
if ((float)v > Avg)
v = 0;
}
TCUsed = totalN;
// If no beat was within typical drift (how would it be possible? well lets cover our ass) then keep the simple
// average calculated earlier, else recalculate average of beats within range
if (totalN)
Avg = totalTC/totalN;
if (ReadyToGuess())
{
if (Avg) // Avg = 0 ? Ahem..
Bpm = 60000 / Avg;
if (Bpm != lastBPM)
{
newBpm(Bpm); // If realtime Bpm has changed since last time, then insert it in the smoothing tab;e
lastBPM = Bpm;
if (cfg_smartbeatsticky && predictionBpm && Confidence >= ((predictionBpm < 90) ? STICKY_THRESHOLD_LOW : STICKY_THRESHOLD))
{
stickyConfidenceCount++;
if (stickyConfidenceCount >= MIN_STICKY)
sticked=1;
}
else
stickyConfidenceCount=0;
}
Bpm = GetBpm();
// Count how many beats we discriminated
for (i=0;i<TCHistSize;i++)
if (halfDiscriminated[i]) hdCount++;
if (hdCount >= TCHistSize/2) // If we removed at least half of our beats, then we are off course. We should double our bpm
{
if (Bpm * 2 < MAX_BPM) // Lets do so only if the doubled bpm is < MAX_BPM
{
doubleBeat();
memset(halfDiscriminated, 0, TCHistSize*sizeof(int)); // Reset discrimination table
}
}
if (Bpm > 500 || Bpm < 0)
{
ResetAdapt();
}
if (Bpm < MIN_BPM)
{
if (++doubleCount > 4) // We're going too slow, lets double our bpm
doubleBeat();
}
else
doubleCount=0;
if (Bpm > MAX_BPM) // We're going too fast, lets slow our bpm by a factor of 2
{
if (++halfCount > 4)
halfBeat();
}
else
halfCount=0;
}
}
void SliderStep(int Ctl, int *slide)
{
*slide += Ctl == IDC_IN ? inInc : outInc;
if (!*slide || *slide == 8) (Ctl == IDC_IN ? inInc : outInc) *= -1;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
int refineBeat(int isBeat)
{
BOOL accepted=FALSE;
BOOL predicted=FALSE;
BOOL resyncin=FALSE;
BOOL resyncout=FALSE;
if (isBeat) // Show the beat received from AVS
SliderStep(IDC_IN, &inSlide);
DWORD TCNow = GetTickCount();
if (songChanged(TCNow))
{
bestConfidence=(int)((float)bestConfidence*0.5);
sticked=0;
stickyConfidenceCount=0;
if (cfg_smartbeatresetnewsong)
ResetAdapt();
}
// Try to predict if this frame should be a beat
if (Bpm && TCNow > predictionLastTC + (60000 / Bpm))
predicted = TRUE;
if (isBeat) // If it is a real beat, do discrimination/guessing and computations, then see if it is accepted
accepted = TCHistStep(TCHist, Avg, halfDiscriminated, &hdPos, &lastTC, TCNow, BEAT_REAL);
// Calculate current Bpm
CalcBPM();
// If prediction Bpm has not yet been set
// or if prediction bpm is too high or too low
// or if 3/4 of our history buffer contains beats within the range of typical drift
// the accept the calculated Bpm as the new prediction Bpm
// This allows keeping the beat going on when the music fades out, and readapt to the new beat as soon as
// the music fades in again
if ((accepted || predicted) && !sticked && (!predictionBpm || predictionBpm > MAX_BPM || predictionBpm < MIN_BPM))
{
if (Confidence >= bestConfidence)
{
/* betterConfidenceCount++;
if (!predictionBpm || betterConfidenceCount == BETTER_CONF_ADOPT)
{*/
forceNewBeat=1;
/* betterConfidenceCount=0;
}*/
}
if (Confidence >= 50)
{
topConfidenceCount++;
if (topConfidenceCount == TOP_CONF_ADOPT)
{
forceNewBeat=1;
topConfidenceCount=0;
}
}
if (forceNewBeat)
{
forceNewBeat=0;
bestConfidence = Confidence;
predictionBpm=Bpm;
}
}
if (!sticked) predictionBpm = Bpm;
Bpm=predictionBpm;
/* resync = (predictionBpm &&
(predictionLastTC < TCNow - (30000/predictionBpm) - (60000/predictionBpm)*0.2) ||
(predictionLastTC < TCNow - (30000/predictionBpm) - (60000/predictionBpm)*0.2));*/
if (predictionBpm && accepted && !predicted)
{
int b=0;
if (TCNow > predictionLastTC + (60000 / predictionBpm)*0.7)
{
resyncin = TRUE;
b = (int)((float)predictionBpm * 1.01);
}
if (TCNow < predictionLastTC + (60000 / predictionBpm)*0.3)
{
resyncout = TRUE;
b = (int)((float)predictionBpm * 0.98);
}
if (!sticked && doResyncBpm && (resyncin || resyncout))
{
newBpm(b);
predictionBpm = GetBpm();
}
}
if (resyncin)
{
predictionLastTC = TCNow;
SliderStep(IDC_OUT, &outSlide);
doResyncBpm=TRUE;
return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 1 : isBeat;
}
if (predicted)
{
predictionLastTC = TCNow;
if (Confidence > 25) TCHistStep(TCHist, Avg, halfDiscriminated, &hdPos, &lastTC, TCNow, BEAT_GUESSED);
SliderStep(IDC_OUT, &outSlide);
doResyncBpm=FALSE;
return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 1 : isBeat;
}
if (resyncout)
{
predictionLastTC = TCNow;
doResyncBpm=TRUE;
return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 0 : isBeat;
}
return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? (predictionBpm ? 0 : isBeat) : isBeat;
}
+56
View File
@@ -0,0 +1,56 @@
/*
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 __BPM_H
#define __BPM_H
#define BEAT_REAL 1
#define BEAT_GUESSED 2
#define MAX_BPM 170
#define MIN_BPM 60
#define BETTER_CONF_ADOPT 2
#define TOP_CONF_ADOPT 8
#define MIN_STICKY 8
#define STICKY_THRESHOLD 70
#define STICKY_THRESHOLD_LOW 85
typedef struct {
DWORD TC; // Tick count
int Type; // Real/guessed
}BeatType;
BOOL CALLBACK DlgProc_Bpm(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
void initBpm(void);
int refineBeat(int isBeat);
#endif
@@ -0,0 +1,22 @@
How to use the custom light position evaluator:
* Init code will be executed each time the window size is changed
or when the effect loads
* Frame code is executed before rendering a new frame
* Beat code is executed when a beat is detected
Predefined variables:
x : Light x position, ranges from 0 (left) to 1 (right) (0.5 = center)
y : Light y position, ranges from 0 (top) to 1 (bottom) (0.5 = center)
isBeat : 1 if no beat, -1 if beat (weird, but old)
isLBeat: same as isBeat but persists according to 'shorter/longer' settings
(usable only with OnBeat checked)
bi: Bump intensity, ranges from 0 (flat) to 1 (max specified bump, default)
You may also use temporary variables accross code segments
Some examples:
Circular move
Init : t=0
Frame: x=0.5+cos(t)*0.3; y=0.5+sin(t)*0.3; t=t+0.1;
Nice motion:
Init : t=0;u=0
Frame: x=0.5+cos(t)*0.3; y=0.5+cos(u)*0.3; t=t+0.1; u=u+0.012;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
/*
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.
*/
void CfgWnd_Create(struct winampVisModule *this_mod);
void CfgWnd_Destroy(void);
void CfgWnd_Populate(int force=0);
void CfgWnd_Unpopulate(int force=0);
void CfgWnd_RePopIfNeeded(void);
extern int cfg_fs_w,cfg_fs_h,cfg_fs_d,cfg_fs_bpp,cfg_fs_fps,cfg_fs_rnd,cfg_fs_flip,cfg_fs_height,cfg_speed,cfg_fs_rnd_time;
extern int cfg_cfgwnd_x,cfg_cfgwnd_y,cfg_cfgwnd_open;
extern int cfg_trans,cfg_trans_amount;
extern int cfg_dont_min_avs;
extern int cfg_smartbeat, cfg_smartbeatsticky, cfg_smartbeatresetnewsong, cfg_smartbeatonlysticky;
extern int cfg_transitions, cfg_transitions2, cfg_transitions_speed, cfg_transition_mode;
extern int cfg_bkgnd_render,cfg_bkgnd_render_color;
extern int cfg_render_prio;
extern char config_pres_subdir[MAX_PATH];
extern HWND g_hwndDlg;
@@ -0,0 +1,11 @@
The color modifier allows you to modify the intensity of each color
channel with respect to itself. For example, you could reverse the red
channel, double the green channel, or half the blue channel.
The code in the 'level' section should adjust the variables
'red', 'green', and 'blue', whose value represent the channel
intensity (0..1).
Code in the 'frame' or 'level' sections can also use the variable
'beat' to detect if it is currently a beat.
Try loading an example via the 'Load Example' button for examples.
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
/*
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.
*/
int DDraw_Init();
void DDraw_Quit(void);
void DDraw_Resize(int w, int h, int dsize);
void DDraw_BeginResize(void);
void DDraw_Enter(int *w, int *h, int **fb1, int **fb2);
void DDraw_Exit(int which);
void DDraw_SetFullScreen(int fs, int w, int h, int dbl, int bps);
int DDraw_IsFullScreen(void);
void DDraw_EnumDispModes(HWND);
double DDraw_translatePoint(POINT p, int isY);
void DDraw_SetStatusText(char *text, int life=0);
int DDraw_IsMode(int w, int h, int bpp);
@@ -0,0 +1,12 @@
The dynamic distance modifier allows you to dynamically (once per frame)
change the source pixels for each ring of pixels out from the center.
In the 'pixel' code section, 'd' represents the distance in pixels
the current ring is from the center, and code can modify it to
change the distance from the center where the source pixels for
that ring would be read. This is a terrible explanation, and if
you want to make a better one send it to me.
Examples:
Zoom in: 'd=d*0.9'
Zoom out: 'd=d*1.1'
Back and forth: pixel='d=d*(1.0+0.1*cos(t));', frame='t=t+0.1'
@@ -0,0 +1 @@
Dynamic movement help goes here (send me some :) )
@@ -0,0 +1,7 @@
Better Dynamic shift help goes here (send me some :)
Variables:
x,y = amount to shift (in pixels - set these)
w,h = width, height (in pixels)
b = isBeat
alpha = alpha value (0.0-1.0) for blend
@@ -0,0 +1,6 @@
Read/write 'enabled' to get/set whether the effect list is enabled for this frame
Read/write 'beat' to get/set whether there is currently a beat
Read/write 'clear' to get/set whether to clear the framebuffer
If the input blend is set to adjustable, 'alphain' can be set from 0.0-1.0
If the output blend is set to adjustable, 'alphaout' can be set from 0.0-1.0
'w' and 'h' are set with the current width and height of the frame
Binary file not shown.
@@ -0,0 +1,576 @@
#include <windows.h>
#include <stdio.h>
#include "Compiler.h"
#include "eval.h"
#define VALUE 258
#define IDENTIFIER 259
#define FUNCTION1 260
#define FUNCTION2 261
#define FUNCTION3 262
#define UMINUS 263
#define UPLUS 264
#define YYSTYPE int
int yyerror(char *);
int yylex(char **exp);
extern int result;
typedef struct
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
} yyltype;
#define YYLTYPE yyltype
#define YYFINAL 51
#define YYFLAG -32768
#define YYNTBASE 21
#define YYTRANSLATE(x) ((unsigned)(x) <= 264 ? yytranslate[x] : 26)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 14, 9, 2, 18,
19, 12, 10, 20, 11, 2, 13, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
17, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 8, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
6, 7, 15, 16
};
static const short yyr1[] = { 0,
21, 21, 22, 23, 23, 23, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 25, 25, 25
};
static const short yyr2[] = { 0,
1, 3, 1, 1, 1, 3, 1, 3, 3, 3,
3, 3, 3, 3, 2, 2, 1, 4, 6, 8
};
static const short yydefact[] = { 0,
3, 4, 0, 0, 0, 0, 0, 0, 5, 7,
1, 17, 0, 0, 0, 0, 4, 16, 15, 0,
0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
0, 6, 14, 13, 11, 12, 8, 9, 10, 18,
0, 0, 0, 0, 19, 0, 0, 20, 0, 0,
0
};
static const short yydefgoto[] = { 49,
9, 10, 11, 12
};
static const short yypact[] = { 19,
-32768, -11, -7, -5, -4, 38, 38, 38,-32768,-32768,
136,-32768, 38, 38, 38, 38,-32768,-32768,-32768, 88,
38, 38, 38, 38, 38, 38, 38, 136, 100, 49,
62,-32768, 41, 54, -9, -9,-32768,-32768,-32768,-32768,
38, 38, 112, 75,-32768, 38, 124,-32768, 12, 27,
-32768
};
static const short yypgoto[] = {-32768,
-32768,-32768, -6,-32768
};
#define YYLAST 150
static const short yytable[] = { 18,
19, 20, 25, 26, 27, 13, 28, 29, 30, 31,
14, 50, 15, 16, 33, 34, 35, 36, 37, 38,
39, 1, 2, 3, 4, 5, 51, 0, 6, 7,
0, 0, 0, 0, 43, 44, 8, 0, 0, 47,
1, 17, 3, 4, 5, 0, 0, 6, 7, 22,
23, 24, 25, 26, 27, 8, 21, 22, 23, 24,
25, 26, 27, 23, 24, 25, 26, 27, 41, 21,
22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
0, 42, 21, 22, 23, 24, 25, 26, 27, 0,
0, 0, 0, 0, 46, 21, 22, 23, 24, 25,
26, 27, 0, 0, 0, 0, 32, 21, 22, 23,
24, 25, 26, 27, 0, 0, 0, 0, 40, 21,
22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
45, 21, 22, 23, 24, 25, 26, 27, 0, 0,
0, 0, 48, 21, 22, 23, 24, 25, 26, 27
};
static const short yycheck[] = { 6,
7, 8, 12, 13, 14, 17, 13, 14, 15, 16,
18, 0, 18, 18, 21, 22, 23, 24, 25, 26,
27, 3, 4, 5, 6, 7, 0, -1, 10, 11,
-1, -1, -1, -1, 41, 42, 18, -1, -1, 46,
3, 4, 5, 6, 7, -1, -1, 10, 11, 9,
10, 11, 12, 13, 14, 18, 8, 9, 10, 11,
12, 13, 14, 10, 11, 12, 13, 14, 20, 8,
9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
-1, 20, 8, 9, 10, 11, 12, 13, 14, -1,
-1, -1, -1, -1, 20, 8, 9, 10, 11, 12,
13, 14, -1, -1, -1, -1, 19, 8, 9, 10,
11, 12, 13, 14, -1, -1, -1, -1, 19, 8,
9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
19, 8, 9, 10, 11, 12, 13, 14, -1, -1,
-1, -1, 19, 8, 9, 10, 11, 12, 13, 14
};
#define YYPURE 1
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYIMPURE
#define YYLEX yylex(&exp)
#endif
#ifndef YYPURE
#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYIMPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
int yynerrs; /* number of parse errors so far */
#endif /* YYIMPURE */
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#define YYINITDEPTH 5000
#define YYMAXDEPTH 5000
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0)
//#ln 131 "bison.simple"
int yyparse(char *exp)
{
register int yystate;
register int yyn;
register short *yyssp;
register YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to shift before error messages enabled */
int yychar1; /* lookahead token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /* the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
int yystacksize = YYINITDEPTH;
#ifndef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
yylval = 0;
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack. */
yyssp = yyss - 1;
yyvsp = yyvs;
/* Push a new state, which is found in yystate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
if (yystacksize >= YYMAXDEPTH)
{
yyerror("internal error: parser stack overflow");
return 2;
}
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
if (yyssp >= yyss + yystacksize - 1) YYABORT;
}
// yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (yychar == YYEMPTY)
{
// yyStackSize = yyssp - (yyss - 1);
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
}
else
{
yychar1 = YYTRANSLATE(yychar);
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
/* count tokens shifted since error; after three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
switch (yyn) {
case 1:
//#ln 32 "cal.y"
{ yyval = yyvsp[0]; result = yyvsp[0]; ;
break;}
case 2:
//#ln 34 "cal.y"
{ {
int i = (int)setVar((int)yyvsp[-2], 0);
int v;
if (i < 0) v=createCompiledValue(0, NULL);
else if (i < EVAL_MAX_VARS) v= createCompiledValue(0, &(varTable[i].value));
else if (i < EVAL_MAX_VARS+100) v= createCompiledValue(0, globalregs+i-EVAL_MAX_VARS);
else v=createCompiledValue(0, NULL);
yyval = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, (int)yyvsp[0]);
result = yyval;
}
;
break;}
case 3:
//#ln 50 "cal.y"
{ yyval = yyvsp[0] ;
break;}
case 4:
//#ln 55 "cal.y"
{ yyval = getVar((int)yyvsp[0]);;
break;}
case 5:
//#ln 57 "cal.y"
{ yyval = yyvsp[0];;
break;}
case 6:
//#ln 59 "cal.y"
{ yyval = yyvsp[-1];;
break;}
case 7:
//#ln 64 "cal.y"
{ yyval = yyvsp[0]; ;
break;}
case 8:
//#ln 66 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, yyvsp[-2], yyvsp[0]);
break;}
case 9:
//#ln 72 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, yyvsp[-2], yyvsp[0]);
break;}
case 10:
//#ln 78 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, yyvsp[-2], yyvsp[0]);
break;}
case 11:
//#ln 84 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_ADD, yyvsp[-2], yyvsp[0]);
break;}
case 12:
//#ln 90 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_SUB, yyvsp[-2], yyvsp[0]);
break;}
case 13:
//#ln 96 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_AND, yyvsp[-2], yyvsp[0]);
break;}
case 14:
//#ln 102 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_OR, yyvsp[-2], yyvsp[0]);
break;}
case 15:
//#ln 108 "cal.y"
{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, yyvsp[0]);
break;}
case 16:
//#ln 114 "cal.y"
{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, yyvsp[0]);
break;}
case 17:
//#ln 120 "cal.y"
{ yyval = yyvsp[0];
break;}
case 18:
//#ln 125 "cal.y"
{ yyval = createCompiledFunction1(MATH_FN, (int)yyvsp[-3], yyvsp[-1]);
break;}
case 19:
//#ln 131 "cal.y"
{ yyval = createCompiledFunction2(MATH_FN, (int)yyvsp[-5], yyvsp[-3], yyvsp[-1]);
break;}
case 20:
//#ln 137 "cal.y"
{ yyval = createCompiledFunction3(MATH_FN, (int)yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]);
break;}
}
/* the action file gets copied in in place of this dollarsign */
//#ln 362 "bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
*++yyvsp = yyval;
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
++yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
#error this should not compile
msg = (char *) xmalloc(size + 15);
strcpy(msg, "syntax error");
if (count < 5)
{
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, yytname[x]);
strcat(msg, "'");
count++;
}
}
yyerror(msg);
free(msg);
}
else
#endif /* YYERROR_VERBOSE */
yyerror("syntax error");
}
//yyerrlab1: /* here on error raised explicitly by an action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (yychar == YYEOF) YYABORT;
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
*++yyvsp = yylval;
yystate = yyn;
goto yynewstate;
}
@@ -0,0 +1,747 @@
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include "Compiler.h"
#include "eval.h"
// defining this allows code to run in different threads at the same time
// it tends however, to be slower. We leave this OFF for AVS, since most of our shit runs in one thread
// anyhow.
//#define NSEEL_REENTRANT_EXECUTION
#ifdef NSEEL_REENTRANT_EXECUTION
#include <malloc.h>
#endif
#define NSEEL_USE_CRITICAL_SECTION g_eval_cs
// note that compiling can only happen in one thread at a time, always.
int g_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
#ifdef NSEEL_USE_CRITICAL_SECTION
CRITICAL_SECTION NSEEL_USE_CRITICAL_SECTION;
#endif
#define LLB_DSIZE (65536-64)
typedef struct _llBlock {
struct _llBlock *next;
int sizeused;
char block[LLB_DSIZE];
} llBlock;
typedef struct _startPtr {
struct _startPtr *next;
void *startptr;
} startPtr;
typedef struct {
int workTablePtr_size;
llBlock *blocks;
void *code;
int code_stats[4];
} codeHandleType;
static llBlock *blocks_head = NULL;
static llBlock *tmpblocks_head = NULL; // used only during compile
#define NSEEL_MAX_TEMPSPACE_ENTRIES 8192
static int g_evallib_computTableTop; // make it abort on potential overflow =)
static int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
static void *__newBlock(llBlock **start,int size);
#define newTmpBlock(x) __newBlock(&tmpblocks_head,x)
#define newBlock(x) __newBlock(&blocks_head,x)
static void freeBlocks(llBlock *start);
char *g_evallib_visdata;
#define DECL_ASMFUNC(x) \
void _asm_##x##(void); \
void _asm_##x##_end(void); \
DECL_ASMFUNC(sin)
DECL_ASMFUNC(cos)
DECL_ASMFUNC(tan)
DECL_ASMFUNC(asin)
DECL_ASMFUNC(acos)
DECL_ASMFUNC(atan)
DECL_ASMFUNC(atan2)
DECL_ASMFUNC(sqr)
DECL_ASMFUNC(sqrt)
DECL_ASMFUNC(pow)
DECL_ASMFUNC(exp)
DECL_ASMFUNC(log)
DECL_ASMFUNC(log10)
DECL_ASMFUNC(abs)
DECL_ASMFUNC(min)
DECL_ASMFUNC(min)
DECL_ASMFUNC(max)
DECL_ASMFUNC(sig)
DECL_ASMFUNC(sign)
DECL_ASMFUNC(rand)
DECL_ASMFUNC(band)
DECL_ASMFUNC(bor)
DECL_ASMFUNC(bnot)
DECL_ASMFUNC(if)
DECL_ASMFUNC(equal)
DECL_ASMFUNC(below)
DECL_ASMFUNC(above)
DECL_ASMFUNC(assign)
DECL_ASMFUNC(add)
DECL_ASMFUNC(sub)
DECL_ASMFUNC(mul)
DECL_ASMFUNC(div)
DECL_ASMFUNC(mod)
DECL_ASMFUNC(or)
DECL_ASMFUNC(and)
DECL_ASMFUNC(uplus)
DECL_ASMFUNC(uminus)
DECL_ASMFUNC(floor)
DECL_ASMFUNC(ceil)
DECL_ASMFUNC(invsqrt)
DECL_ASMFUNC(exec2)
DECL_ASMFUNC(getosc)
DECL_ASMFUNC(getspec)
DECL_ASMFUNC(gettime)
DECL_ASMFUNC(getmouse)
DECL_ASMFUNC(setmousepos)
static functionType fnTable1[36] = {
{ "if", _asm_if,_asm_if_end, 3 },
{ "sin", _asm_sin,_asm_sin_end, 1 },
{ "cos", _asm_cos,_asm_cos_end, 1 },
{ "tan", _asm_tan,_asm_tan_end, 1 },
{ "asin", _asm_asin,_asm_asin_end, 1 },
{ "acos", _asm_acos,_asm_acos_end, 1 },
{ "atan", _asm_atan,_asm_atan_end, 1 },
{ "atan2", _asm_atan2,_asm_atan2_end, 2 },
{ "sqr", _asm_sqr,_asm_sqr_end, 1 },
{ "sqrt", _asm_sqrt,_asm_sqrt_end, 1 },
{ "pow", _asm_pow,_asm_pow_end, 2 },
{ "exp", _asm_exp,_asm_exp_end, 1 },
{ "log", _asm_log,_asm_log_end, 1 },
{ "log10", _asm_log10,_asm_log10_end, 1 },
{ "abs", _asm_abs,_asm_abs_end, 1 },
{ "min", _asm_min,_asm_min_end, 2 },
{ "max", _asm_max,_asm_max_end, 2 },
{ "sigmoid",_asm_sig,_asm_sig_end, 2 } ,
{ "sign", _asm_sign,_asm_sign_end, 1 } ,
{ "rand", _asm_rand,_asm_rand_end, 1 } ,
{ "band", _asm_band,_asm_band_end, 2 } ,
{ "bor", _asm_bor,_asm_bor_end, 2 } ,
{ "bnot", _asm_bnot,_asm_bnot_end, 1 } ,
{ "equal", _asm_equal,_asm_equal_end, 2 },
{ "below", _asm_below,_asm_below_end, 2 },
{ "above", _asm_above,_asm_above_end, 2 },
{ "floor", _asm_floor,_asm_floor_end, 1 },
{ "ceil", _asm_ceil,_asm_ceil_end, 1 },
{ "invsqrt", _asm_invsqrt,_asm_invsqrt_end, 1 },
{ "assign",_asm_assign,_asm_assign_end,2},
{ "exec2",_asm_exec2,_asm_exec2_end,2},
// these will be seperated since they are AVS specific
{ "getosc", _asm_getosc,_asm_getosc_end,3 },
{ "getspec",_asm_getspec,_asm_getspec_end,3 },
{ "gettime", _asm_gettime,_asm_gettime_end,1},
{ "getkbmouse",_asm_getmouse,_asm_getmouse_end,1},
{ "setmousepos",_asm_setmousepos,_asm_setmousepos_end,2},
};
functionType *getFunctionFromTable(int idx)
{
// todo: add API for adding functions to a seperate table :)
if (idx<0 || idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) return 0;
return fnTable1+idx;
}
//---------------------------------------------------------------------------------------------------------------
static void *realAddress(void *fn, void *fn_e, int *size)
{
#ifdef _DEBUG
// Debug Mode
*siiiize=0; // fucko, need to figure this out
char *ptr = (char *)fn;
return ptr + (*(int *)(ptr+1))+5;
#else
// Release Mode
*size = (int)fn_e - (int) fn;
return fn;
#endif
}
//---------------------------------------------------------------------------------------------------------------
static void freeBlocks(llBlock *start)
{
while (start)
{
llBlock *llB = start->next;
GlobalFree(start);
start=llB;
}
}
//---------------------------------------------------------------------------------------------------------------
static void *__newBlock(llBlock **start, int size)
{
llBlock *llb;
int alloc_size;
if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
{
void *t=(*start)->block+(*start)->sizeused;
(*start)->sizeused+=size;
return t;
}
alloc_size=sizeof(llBlock);
if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// benski> CUT: llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
llb->sizeused=size;
llb->next = *start;
*start = llb;
return llb->block;
}
#define X86_MOV_EAX_DIRECTVALUE 0xB8
#define X86_MOV_ESI_DIRECTVALUE 0xBE
#define X86_MOV_ESI_DIRECTMEMVALUE 0x358B
#define X86_PUSH_EAX 0x50
#define X86_POP_EBX 0x5B
#define X86_POP_ECX 0x59
#define X86_MOV_ESI_EDI 0xF78B
#define X86_PUSH_ESI 0x56
#define X86_POP_ESI 0x5E
#define X86_RET 0xC3
//---------------------------------------------------------------------------------------------------------------
static int *findFBlock(char *p)
{
while (*(int *)p != 0xFFFFFFFF) p++;
return (int*)p;
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledValue(double value, double *addrValue)
{
unsigned char *block;
double *dupValue;
block=(unsigned char *)newTmpBlock(4+5);
if (addrValue == NULL)
{
l_stats[3]+=sizeof(double);
*(dupValue = (double *)newBlock(sizeof(double))) = value;
}
else
dupValue = addrValue;
((int*)block)[0]=5;
block[4]=X86_MOV_EAX_DIRECTVALUE; // mov eax, <value>
*(int *)(block+5) = (int)dupValue;
return ((int)(block));
}
//---------------------------------------------------------------------------------------------------------------
int getFunctionAddress(int fntype, int fn, int *size)
{
switch (fntype)
{
case MATH_SIMPLE:
switch (fn)
{
case FN_ASSIGN:
return (int)realAddress(_asm_assign,_asm_assign_end,size);
case FN_ADD:
return (int)realAddress(_asm_add,_asm_add_end,size);
case FN_SUB:
return (int)realAddress(_asm_sub,_asm_sub_end,size);
case FN_MULTIPLY:
return (int)realAddress(_asm_mul,_asm_mul_end,size);
case FN_DIVIDE:
return (int)realAddress(_asm_div,_asm_div_end,size);
case FN_MODULO:
return (int)realAddress(_asm_mod,_asm_mod_end,size);
case FN_AND:
return (int)realAddress(_asm_and,_asm_and_end,size);
case FN_OR:
return (int)realAddress(_asm_or,_asm_or_end,size);
case FN_UPLUS:
return (int)realAddress(_asm_uplus,_asm_uplus_end,size);
case FN_UMINUS:
return (int)realAddress(_asm_uminus,_asm_uminus_end,size);
}
case MATH_FN:
{
functionType *p=getFunctionFromTable(fn);
if (!p)
{
if (size) *size=0;
return 0;
}
return (int)realAddress(p->afunc,p->func_e,size);
}
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
{
int sizes1=((int *)code1)[0];
int sizes2=((int *)code2)[0];
int sizes3=((int *)code3)[0];
if (fntype == MATH_FN && fn == 0) // special case: IF
{
void *func3;
int size;
int *ptr;
char *block;
unsigned char *newblock2,*newblock3;
newblock2=newBlock(sizes2+1);
memcpy(newblock2,(char*)code2+4,sizes2);
newblock2[sizes2]=X86_RET;
newblock3=newBlock(sizes3+1);
memcpy(newblock3,(char*)code3+4,sizes3);
newblock3[sizes3]=X86_RET;
l_stats[2]+=sizes2+sizes3+2;
func3 = realAddress(_asm_if,_asm_if_end,&size);
block=(char *)newTmpBlock(4+sizes1+size);
((int*)block)[0]=sizes1+size;
memcpy(block+4,(char*)code1+4,sizes1);
ptr=(int *)(block+4+sizes1);
memcpy(ptr,func3,size);
ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;
return (int)block;
}
else
{
int size2;
unsigned char *block;
unsigned char *outp;
int myfunc;
myfunc = getFunctionAddress(fntype, fn, &size2);
block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);
((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
outp=block+4;
memcpy(outp,(char*)code1+4,sizes1);
outp+=sizes1;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code2+4,sizes2);
outp+=sizes2;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code3+4,sizes3);
outp+=sizes3;
*outp++ = X86_POP_EBX;
*outp++ = X86_POP_ECX;
memcpy(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction2(int fntype, int fn, int code1, int code2)
{
int size2;
unsigned char *block;
unsigned char *outp;
int myfunc;
int sizes1=((int *)code1)[0];
int sizes2=((int *)code2)[0];
myfunc = getFunctionAddress(fntype, fn, &size2);
block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);
((int*)block)[0]=2+size2+sizes1+sizes2;
outp=block+4;
memcpy(outp,(char*)code1+4,sizes1);
outp+=sizes1;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code2+4,sizes2);
outp+=sizes2;
*outp++ = X86_POP_EBX;
memcpy(block+4+2+sizes1+sizes2,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction1(int fntype, int fn, int code)
{
int size,size2;
char *block;
int myfunc;
void *func1;
size =((int *)code)[0];
func1 = (void *)(code+4);
myfunc = getFunctionAddress(fntype, fn, &size2);
block=(char *)newTmpBlock(4+size+size2);
((int*)block)[0]=size+size2;
memcpy(block+4, func1, size);
memcpy(block+size+4,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
static char *preprocessCode(char *expression)
{
int len=0;
int alloc_len=strlen(expression)+1+64;
char *buf=(char *)malloc(alloc_len);
while (*expression)
{
if (len > alloc_len-32)
{
alloc_len = len+128;
buf=(char*)realloc(buf,alloc_len);
}
if (expression[0] == '/')
{
if (expression[1] == '/')
{
expression+=2;
while (expression[0] && expression[0] != '\r' && expression[0] != '\n') expression++;
}
else if (expression[1] == '*')
{
expression+=2;
while (expression[0] && (expression[0] != '*' || expression[1] != '/')) expression++;
if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
}
else
{
char c=buf[len++]=*expression++;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
}
}
else if (expression[0] == '$')
{
if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
{
static char *str="3.141592653589793";
expression+=3;
memcpy(buf+len,str,17);
len+=17; //strlen(str);
l_stats[0]+=17;
}
else if (toupper(expression[1]) == 'E')
{
static char *str="2.71828183";
expression+=2;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
l_stats[0]+=10;
}
if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
{
static char *str="1.61803399";
expression+=4;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
l_stats[0]+=10;
}
else
{
char c = buf[len++]=*expression++;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
}
}
else
{
char c=*expression++;
if (c == '\r' || c == '\n' || c == '\t') c=' ';
buf[len++]=c;
if (c != ' ') l_stats[0]++;
}
}
buf[len]=0;
return buf;
}
int g_log_errors;
static void movestringover(char *str, int amount)
{
char tmp[1024+8];
int l=(int)strlen(str);
l=min(1024-amount-1,l);
memcpy(tmp,str,l+1);
while (l >= 0 && tmp[l]!='\n') l--;
l++;
tmp[l]=0;//ensure we null terminate
memcpy(str+amount,tmp,l+1);
}
//------------------------------------------------------------------------------
int compileCode(char *_expression)
{
char *expression,*expression_start;
int computable_size=0;
codeHandleType *handle;
startPtr *scode=NULL;
startPtr *startpts=NULL;
if (!_expression || !*_expression) return 0;
if (!varTable) return 0;
#ifdef NSEEL_USE_CRITICAL_SECTION
EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
blocks_head=0;
tmpblocks_head=0;
memset(l_stats,0,sizeof(l_stats));
handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
if (!handle)
{
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
return 0;
}
memset(handle,0,sizeof(codeHandleType));
expression_start=expression=preprocessCode(_expression);
while (*expression)
{
startPtr *tmp;
char *expr;
colCount=0;
// single out segment
while (*expression == ';' || *expression == ' ') expression++;
if (!*expression) break;
expr=expression;
while (*expression && *expression != ';') expression++;
if (*expression) *expression++ = 0;
// parse
tmp=(startPtr*) newTmpBlock(sizeof(startPtr));
if (!tmp) break;
g_evallib_computTableTop=0;
tmp->startptr=compileExpression(expr);
if (computable_size < g_evallib_computTableTop)
{
computable_size=g_evallib_computTableTop;
}
if (g_evallib_computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES-32)
{
tmp->startptr=0; // overflow in this mode
}
if (!tmp->startptr)
{
if (g_log_errors)
{
int l=strlen(expr);
if (l > 512) l=512;
movestringover(last_error_string,l+2);
memcpy(last_error_string,expr,l);
last_error_string[l]='\r';
last_error_string[l+1]='\n';
}
scode=NULL;
break;
}
tmp->next=NULL;
if (!scode) scode=startpts=tmp;
else
{
scode->next=tmp;
scode=tmp;
}
}
// check to see if failed on the first startingCode
if (!scode)
{
freeBlocks(blocks_head); // free blocks
handle=NULL; // return NULL (after resetting blocks_head)
}
else
{
// now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
unsigned char *writeptr;
int size=1; // for ret at end :)
startPtr *p;
p=startpts;
while (p)
{
size+=2; // mov esi, edi
size+=*(int *)p->startptr;
p=p->next;
}
handle->code = newBlock(size);
if (handle->code)
{
writeptr=(unsigned char *)handle->code;
p=startpts;
while (p)
{
int thissize=*(int *)p->startptr;
*(unsigned short *)writeptr= X86_MOV_ESI_EDI;
writeptr+=2;
memcpy(writeptr,(char*)p->startptr + 4,thissize);
writeptr += thissize;
p=p->next;
}
*writeptr=X86_RET; // ret
l_stats[1]=size;
}
handle->blocks = blocks_head;
handle->workTablePtr_size=(computable_size+4) * sizeof(double);
}
freeBlocks(tmpblocks_head); // free blocks
tmpblocks_head=0;
blocks_head=0;
if (handle)
{
memcpy(handle->code_stats,l_stats,sizeof(l_stats));
g_evallib_stats[0]+=l_stats[0];
g_evallib_stats[1]+=l_stats[1];
g_evallib_stats[2]+=l_stats[2];
g_evallib_stats[3]+=l_stats[3];
g_evallib_stats[4]++;
}
memset(l_stats,0,sizeof(l_stats));
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
free(expression_start);
return (int)handle;
}
//------------------------------------------------------------------------------
void executeCode(int handle, char visdata[2][2][576])
{
#ifdef NSEEL_REENTRANT_EXECUTION
int baseptr;
#else
static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
int baseptr = (int) _tab;
#endif
codeHandleType *h = (codeHandleType *)handle;
if (!h || !h->code) return;
#ifdef NSEEL_USE_CRITICAL_SECTION
EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
g_evallib_visdata=(char*)visdata;
#ifdef NSEEL_REENTRANT_EXECUTION
baseptr = (int) alloca(h->workTablePtr_size);
if (!baseptr) return;
#endif
{
int startPoint=(int)h->code;
__asm
{
mov ebx, baseptr
mov eax, startPoint
pushad // Lets cover our ass
mov edi, ebx
call eax
popad
}
}
g_evallib_visdata=NULL;
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
}
//------------------------------------------------------------------------------
void freeCode(int handle)
{
codeHandleType *h = (codeHandleType *)handle;
if (h != NULL)
{
g_evallib_stats[0]-=h->code_stats[0];
g_evallib_stats[1]-=h->code_stats[1];
g_evallib_stats[2]-=h->code_stats[2];
g_evallib_stats[3]-=h->code_stats[3];
g_evallib_stats[4]--;
freeBlocks(h->blocks);
}
}
//------------------------------------------------------------------------------
void resetVars(varType *vars)
{
#ifdef NSEEL_USE_CRITICAL_SECTION
if (vars) EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
varTable=vars;
#ifdef NSEEL_USE_CRITICAL_SECTION
if (!vars) LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
}
@@ -0,0 +1,47 @@
#ifndef __COMPILER_H
#define __COMPILER_H
#define FN_ASSIGN 0
#define FN_MULTIPLY 1
#define FN_DIVIDE 2
#define FN_MODULO 3
#define FN_ADD 4
#define FN_SUB 5
#define FN_AND 6
#define FN_OR 7
#define FN_UMINUS 8
#define FN_UPLUS 9
#define MATH_SIMPLE 0
#define MATH_FN 1
#ifdef __cplusplus
extern "C" {
#endif
int compileCode(char *exp);
void executeCode(int handle, char visdata[2][2][576]);
void freeCode(int handle);
typedef struct {
char *name;
void *afunc;
void *func_e;
int nParams;
} functionType;
extern functionType *getFunctionFromTable(int idx);
int createCompiledValue(double value, double *addrValue);
int createCompiledFunction1(int fntype, int fn, int code);
int createCompiledFunction2(int fntype, int fn, int code1, int code2);
int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,6 @@
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>
Binary file not shown.
@@ -0,0 +1,53 @@
/*
* Bob Denny 28-Aug-82 Remove reference to FILE *lexin to
* eliminate dependency on standard I/O library. Only
* lexgetc() used it, and it's there now.
* Add EOF definition for standalone uses.
* Corrected comment for llnxtmax.
*
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C. Removed
* equivalence of yylval and lexval since
* a multi-typed parser wants yylval to be
* typed to be the union of the types (YYSTYPE).
*/
/*
* lex library header file -- accessed through
* #include <lex.h>
*/
#include <stdio.h>
/*
* Description of scanning tables. The entries at the front of
* the struct must remain in place for the assembler routines to find.
*/
struct lextab {
int llendst; /* Last state number */
char *lldefault; /* Default state table */
char *llnext; /* Next state table */
char *llcheck; /* Check table */
int *llbase; /* Base table */
int llnxtmax; /* Last in next table */
int (*llmove)(); /* Move between states */
char *llfinal; /* Final state descriptions */
int (*llactr)(); /* Action routine */
int *lllook; /* Look ahead vector if != NULL */
char *llign; /* Ignore char vec if != NULL */
char *llbrk; /* Break char vec if != NULL */
char *llill; /* Illegal char vec if != NULL */
};
#define NBPW 16
#define LEXERR 256
#define LEXSKIP (-1)
#define EOF (-1)
//#define NULL (0)
#define LEXECHO(fp) {lexecho((fp));}
#define lextext llbuf
#define lexlast llend
extern FILE *lexin;
extern llstin();
@@ -0,0 +1,20 @@
/*
* lexget.c
*
* Bob Denny 28-Aug-82 Move stdio dependencies to lexerr(), lexget(),
* lexech() and mapch(). This is one of 4 modules
* in lexlib which depend upon the standard I/O package.
*
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C.
*/
#include <stdio.h>
#include <lex.h>
extern char expression[4096];
extern int pos;
lexgetc()
{
char c = expression[pos];
if (c) pos++;
return( c != 0 ? c : -1);
}
@@ -0,0 +1,23 @@
/*
* lexswitch -- switch lex tables
*/
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>
extern struct lextab *_tabp;
struct lextab *
lexswitch(lp)
struct lextab *lp;
{
register struct lextab *olp;
olp = _tabp;
_tabp = lp;
return(olp);
}
@@ -0,0 +1,260 @@
/*
* Created by IBM PC LEX from file "scan.l"
* - for use with standard I/O
*/
#include <stdio.h>
#include <lex.h>
#define LL16BIT int
int _lmovb(struct lextab *lp, int c, int st)
{
int base;
while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
(lp->llcheck[base] & 0377) != st) {
if (st != lp->llendst) {
base = lp->lldefault[st] & 0377;
st = base;
}
else
return(-1);
}
return(lp->llnext[base]&0377);
}
int lexval;
char lbuf[];
#define YYSTYPE int
#include "cal_tab.h"
int c;
extern YYSTYPE yylval;
int translate(int type);
void count(void);
void setLastVar(void);
int lookup(int *typeOfObject);
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
int _Alextab(__na__)
{
if (__na__ >= 0 && __na__ <= 19) count();
switch (__na__)
{
case 0: yylval = translate(HEXCONST); return VALUE;
case 1: yylval = translate(INTCONST); return VALUE;
case 2: yylval = translate(INTCONST); return VALUE;
case 3: yylval = translate(DBLCONST); return VALUE;
case 4:
case 5: setLastVar(); yylval = lookup(&__na__); return __na__;
case 6: return '+';
case 7: return '-';
case 8: return '*';
case 9: return '/';
case 10: return '%';
case 11: return '&';
case 12: return '|';
case 13: return '(';
case 14: return ')';
case 15: return '=';
case 16: return ',';
case 17: return ';';
}
return (LEXSKIP);
}
char _Flextab[] =
{
1, 18, 17, 16, 15, 14, 13, 12,
11, 10, 9, 8, 7, 6, 4, 5,
5, 4, 4, 3, 3, 3, 3, 4,
0, 4, 5, 0, 5, 4, 1, 3,
0, 2, -1, 1, -1,
};
char _Nlextab[] =
{
36, 36, 36, 36, 36, 36, 36, 36,
36, 1, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
1, 36, 36, 36, 36, 9, 8, 36,
6, 5, 11, 13, 3, 12, 19, 10,
30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 36, 2, 36, 4, 36, 36,
36, 29, 29, 29, 29, 29, 29, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 36, 36, 36, 36, 18,
36, 29, 29, 29, 29, 29, 23, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 14, 18,
18, 18, 18, 36, 7, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 36,
36, 36, 36, 36, 36, 36, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
36, 36, 36, 36, 17, 36, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 36, 36, 36, 36, 36, 36,
36, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 36, 36, 36, 36, 16,
36, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 36,
20, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 36, 36, 36, 36, 36,
36, 36, 25, 25, 25, 25, 25, 25,
36, 24, 36, 36, 36, 36, 36, 36,
20, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 25, 25, 25, 25, 25, 25,
36, 24, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 36, 36, 36, 36,
36, 36, 36, 28, 28, 28, 28, 28,
28, 36, 27, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 28, 28, 28, 28, 28,
28, 31, 27, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 36, 36, 36,
36, 36, 36, 36, 34, 34, 34, 33,
34, 34, 36, 32, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 34, 34, 34, 33,
34, 34, 36, 32, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 36, 36,
36, 36, 36, 36, 36, 34, 34, 34,
34, 34, 34, 36, 32, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 34, 34, 34,
34, 34, 34, 36, 32,
};
char _Clextab[] =
{
-1, -1, -1, -1, -1, -1, -1, -1,
-1, 0, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
0, -1, -1, -1, -1, 0, 0, -1,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, -1, 0, -1, 0, -1, -1,
-1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, -1, -1, -1, 0,
-1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, 0, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, -1,
-1, -1, -1, -1, -1, -1, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
-1, -1, -1, -1, 14, -1, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, -1, -1, -1, -1, -1, -1,
-1, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, -1, -1, -1, -1, 15,
-1, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, -1,
19, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, -1, -1, -1, -1, -1,
-1, -1, 23, 23, 23, 23, 23, 23,
-1, 23, -1, -1, -1, -1, -1, -1,
19, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 23, 23, 23, 23, 23, 23,
-1, 23, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, -1, -1, -1, -1,
-1, -1, -1, 26, 26, 26, 26, 26,
26, -1, 26, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 26, 26, 26, 26, 26,
26, 30, 26, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, -1, -1, -1,
-1, -1, -1, -1, 30, 30, 30, 30,
30, 30, -1, 30, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 30, 30, 30, 30,
30, 30, -1, 30, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, -1, -1,
-1, -1, -1, -1, -1, 33, 33, 33,
33, 33, 33, -1, 33, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 33, 33, 33,
33, 33, 33, -1, 33,
};
char _Dlextab[] =
{
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
15, 14, 14, 36, 36, 20, 19, 14,
14, 23, 15, 15, 26, 23, 36, 19,
36, 36, 33, 30,
};
int _Blextab[] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 77, 152,
0, 0, 0, 227, 237, 0, 0, 249,
0, 0, 306, 0, 0, 0, 363, 0,
0, 420, 0, 0, 0,
};
struct lextab lextab = {
36,
_Dlextab,
_Nlextab,
_Clextab,
_Blextab,
524,
_lmovb,
_Flextab,
_Alextab,
NULL,
0,
0,
0,
};
@@ -0,0 +1,6 @@
/*
* This is linked from lexlib to resolve a global in yylex which
* will be undefined if the user grammar has not defined any rules
* with right-context (look-ahead)
*/
char *llsave[1]; /* Look ahead buffer */
@@ -0,0 +1,29 @@
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>
_lmovb(lp, c, st)
register int c, st;
register struct lextab *lp;
{
int base;
while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
(lp->llcheck[base] & 0377) != st) {
if (st != lp->llendst) {
/*
* This miscompiled on Decus C many years ago:
* st = lp->lldefault[st] & 0377;
*/
base = lp->lldefault[st] & 0377;
st = base;
}
else
return(-1);
}
return(lp->llnext[base]&0377);
}
@@ -0,0 +1,54 @@
%{
#define YYSTYPE double
#include "cal_tab.h"
int c;
extern YYSTYPE yylval;
double translate(int type);
void count(void);
void setLastVar(void);
int lookup(int *typeOfObject);
struct lextab *lexswitch(struct lextab *lp);
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
%}
digit = [0-9];
letter = [a-zA-Z_];
hex = [a-fA-F0-9];
/* -- */
space = [\40];
/*number = (digit* | "-" digit*);*/
number = digit*;
exp = [Ee] number;
doubl = number "." (digit* | digit* exp);
%%
hex hex* [hH] { count(); yylval = translate(HEXCONST); return VALUE; }
digit* { count(); yylval = translate(INTCONST); return VALUE; }
digit digit* [Dd] { count(); yylval = translate(INTCONST); return VALUE; }
doubl { count(); yylval = translate(DBLCONST); return VALUE; }
letter* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
letter (letter|digit)* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
'+' { count(); return '+'; }
'-' { count(); return '-'; }
'*' { count(); return '*'; }
'/' { count(); return '/'; }
'%' { count(); return '%'; }
'&' { count(); return '&'; }
'|' { count(); return '|'; }
'(' { count(); return '('; }
')' { count(); return ')'; }
'=' { count(); return '='; }
',' { count(); return ','; }
';' { count(); return ';'; }
[ \t\v\f] { count(); }
. { count(); }
%%
@@ -0,0 +1,143 @@
#include <lex.h>
#define ERROR 256 /* yacc's value */
static int llset(void);
static int llinp(char **exp);
static int lexgetc(char **exp)
{
char c= **exp;
if (c) (*exp)++;
return( c != 0 ? c : -1);
}
static int tst__b(register int c, char tab[])
{
return (tab[(c >> 3) & 037] & (1 << (c & 07)) );
}
static char *llsave[16]; /* Look ahead buffer */
static char llbuf[100]; /* work buffer */
static char *llp1 = &llbuf[0]; /* pointer to next avail. in token */
static char *llp2 = &llbuf[0]; /* pointer to end of lookahead */
static char *llend = &llbuf[0]; /* pointer to end of token */
static char *llebuf = &llbuf[sizeof llbuf];
static int lleof;
static int yyline = 0;
extern struct lextab lextab;
int gettoken(char *lltb, int lltbsiz)
{
register char *lp, *tp, *ep;
tp = lltb;
ep = tp+lltbsiz-1;
for (lp = llbuf; lp < llend && tp < ep;)
*tp++ = *lp++;
*tp = 0;
return(tp-lltb);
}
int yylex(char **exp)
{
register int c, st;
int final, l, llk, i;
register struct lextab *lp;
char *cp;
while (1)
{
llk = 0;
if (llset()) return(0);
st = 0;
final = -1;
lp = &lextab;
do {
if (lp->lllook && (l = lp->lllook[st])) {
for (c=0; c<NBPW; c++)
if (l&(1<<c))
llsave[c] = llp1;
llk++;
}
if ((i = lp->llfinal[st]) != -1) {
final = i;
llend = llp1;
}
if ((c = llinp(exp)) < 0)
break;
if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
llp1--;
break;
}
} while ((st = (*lp->llmove)(lp, c, st)) != -1);
if (llp2 < llp1)
llp2 = llp1;
if (final == -1) {
llend = llp1;
if (st == 0 && c < 0)
return(0);
if ((cp = lp->llill) && tst__b(c, cp)) {
continue;
}
return(ERROR);
}
if (c = (final >> 11) & 037)
llend = llsave[c-1];
if ((c = (*lp->llactr)(final&03777)) >= 0)
return(c);
}
}
void llinit(viud)
{
llp1 = llp2 = llend = llbuf;
llebuf = llbuf + sizeof(llbuf);
lleof = yyline = 0;
}
static int llinp(char **exp)
{
register c;
register struct lextab *lp;
register char *cp;
lp = &lextab;
cp = lp->llign; /* Ignore class */
for (;;) {
/*
* Get the next character from the save buffer (if possible)
* If the save buffer's empty, then return EOF or the next
* input character. Ignore the character if it's in the
* ignore class.
*/
c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc(exp);
if (c >= 0) { /* Got a character? */
if (cp && tst__b(c, cp))
continue; /* Ignore it */
if (llp1 >= llebuf) { /* No, is there room? */
return -1;
}
*llp1++ = c; /* Store in token buff */
} else
lleof = 1; /* Set EOF signal */
return(c);
}
}
static int llset(void)
/*
* Return TRUE if EOF and nothing was moved in the look-ahead buffer
*/
{
register char *lp1, *lp2;
for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
*lp1++ = *lp2++;
llend = llp1 = llbuf;
llp2 = lp1;
return(lleof && lp1 == llbuf);
}
@@ -0,0 +1,334 @@
extern int timeclock;
int yyerror; /* Yyerror and yycost are set by guards. */
int yycost; /* If yyerror is set to a nonzero value by a */
/* guard, the reduction with which the guard */
/* is associated is not performed, and the */
/* error recovery mechanism is invoked. */
/* Yycost indicates the cost of performing */
/* the reduction given the attributes of the */
/* symbols. */
/* YYMAXDEPTH indicates the size of the parser's state and value */
/* stacks. */
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 500
#endif
/* YYMAXRULES must be at least as large as the number of rules that */
/* could be placed in the rule queue. That number could be determined */
/* from the grammar and the size of the stack, but, as yet, it is not. */
#ifndef YYMAXRULES
#define YYMAXRULES 100
#endif
#ifndef YYMAXBACKUP
#define YYMAXBACKUP 100
#endif
short yyss[YYMAXDEPTH]; /* the state stack */
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
short yyrq[YYMAXRULES]; /* the rule queue */
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
YYSTYPE yytval; /* the semantic value for the state */
/* at the top of the state stack. */
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
YYLTYPE yytloc; /* location data for the state at the */
/* top of the state stack */
int yynunlexed;
short yyunchar[YYMAXBACKUP];
YYSTYPE yyunval[YYMAXBACKUP];
YYLTYPE yyunloc[YYMAXBACKUP];
short *yygssp; /* a pointer to the top of the state */
/* stack; only set during error */
/* recovery. */
YYSTYPE *yygvsp; /* a pointer to the top of the value */
/* stack; only set during error */
/* recovery. */
YYLTYPE *yyglsp; /* a pointer to the top of the */
/* location stack; only set during */
/* error recovery. */
/* Yyget is an interface between the parser and the lexical analyzer. */
/* It is costly to provide such an interface, but it avoids requiring */
/* the lexical analyzer to be able to back up the scan. */
yyget()
{
if (yynunlexed > 0)
{
yynunlexed--;
yychar = yyunchar[yynunlexed];
yylval = yyunval[yynunlexed];
yylloc = yyunloc[yynunlexed];
}
else if (yychar <= 0)
yychar = 0;
else
{
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
}
}
yyunlex(chr, val, loc)
int chr;
YYSTYPE val;
YYLTYPE loc;
{
yyunchar[yynunlexed] = chr;
yyunval[yynunlexed] = val;
yyunloc[yynunlexed] = loc;
yynunlexed++;
}
yyrestore(first, last)
register short *first;
register short *last;
{
register short *ssp;
register short *rp;
register int symbol;
register int state;
register int tvalsaved;
ssp = yygssp;
yyunlex(yychar, yylval, yylloc);
tvalsaved = 0;
while (first != last)
{
symbol = yystos[*ssp];
if (symbol < YYNTBASE)
{
yyunlex(symbol, yytval, yytloc);
tvalsaved = 1;
ssp--;
}
ssp--;
if (first == yyrq)
first = yyrq + YYMAXRULES;
first--;
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
{
if (symbol < YYNTBASE)
state = yytable[yypact[*ssp] + symbol];
else
{
state = yypgoto[symbol - YYNTBASE] + *ssp;
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
state = yytable[state];
else
state = yydefgoto[symbol - YYNTBASE];
}
*++ssp = state;
}
}
if ( ! tvalsaved && ssp > yyss)
{
yyunlex(yystos[*ssp], yytval, yytloc);
ssp--;
}
yygssp = ssp;
}
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register short *yyrq0;
register short *yyptr;
register YYSTYPE *yyvsp;
int yylen;
YYLTYPE *yylsp;
short *yyrq1;
short *yyrq2;
yystate = 0;
yyssp = yyss - 1;
yyvsp = yyvs - 1;
yylsp = yyls - 1;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
yynewstate:
if (yyssp >= yyss + YYMAXDEPTH - 1)
{
yyabort("Parser Stack Overflow");
YYABORT;
}
*++yyssp = yystate;
yyresume:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
yyn += yychar;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
goto yydefault;
yyn = yytable[yyn];
if (yyn < 0)
{
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
yystate = yyn;
yyptr = yyrq2;
while (yyptr != yyrq1)
{
yyn = *yyptr++;
yylen = yyr2[yyn];
yyvsp -= yylen;
yylsp -= yylen;
yyguard(yyn, yyvsp, yylsp);
if (yyerror)
goto yysemerr;
yyaction(yyn, yyvsp, yylsp);
*++yyvsp = yyval;
yylsp++;
if (yylen == 0)
{
yylsp->timestamp = timeclock;
yylsp->first_line = yytloc.first_line;
yylsp->first_column = yytloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
if (yyptr == yyrq + YYMAXRULES)
yyptr = yyrq;
}
if (yystate == YYFINAL)
YYACCEPT;
yyrq2 = yyptr;
yyrq1 = yyrq0;
*++yyvsp = yytval;
*++yylsp = yytloc;
yytval = yylval;
yytloc = yylloc;
yyget();
goto yynewstate;
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
yyreduce:
*yyrq0++ = yyn;
if (yyrq0 == yyrq + YYMAXRULES)
yyrq0 = yyrq;
if (yyrq0 == yyrq2)
{
yyabort("Parser Rule Queue Overflow");
YYABORT;
}
yyssp -= yyr2[yyn];
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yysemerr:
*--yyptr = yyn;
yyrq2 = yyptr;
yyvsp += yyr2[yyn];
yyerrlab:
yygssp = yyssp;
yygvsp = yyvsp;
yyglsp = yylsp;
yyrestore(yyrq0, yyrq2);
yyrecover();
yystate = *yygssp;
yyssp = yygssp;
yyvsp = yygvsp;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
goto yyresume;
}
$
@@ -0,0 +1,577 @@
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
//#ln 3 "bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* Not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
#include <alloca.h>
#endif /* Sparc. */
#endif /* Not GNU C. */
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
as one case of the switch. */
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(token, value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ yychar = (token), yylval = (value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ yyerror ("Syntax error, cannot back up!"); YYERROR; } \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYIMPURE
#define YYLEX yylex()
#endif
#ifndef YYPURE
#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYIMPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
#ifdef YYLSP_NEEDED
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
#endif
int yynerrs; /* number of parse errors so far */
#endif /* YYIMPURE */
#if YYDEBUG != 0
int yydebug; /* nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#ifndef YYINITDEPTH
#define YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can grow to
(effective only if the built-in stack extension method is used). */
#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__yy_bcopy (from, to, count)
char *from;
char *to;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
//#ln 131 "bison.simple"
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to shift before error messages enabled */
int yychar1; /* lookahead token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /* the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
#ifdef YYLSP_NEEDED
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
#define YYPOPSTACK (yyvsp--, yysp--, yylsp--)
#else
#define YYPOPSTACK (yyvsp--, yysp--)
#endif
int yystacksize = YYINITDEPTH;
#ifndef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#ifdef YYLSP_NEEDED
YYLTYPE yylloc;
#endif
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Starting parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack. */
yyssp = yyss - 1;
yyvsp = yyvs;
#ifdef YYLSP_NEEDED
yylsp = yyls;
#endif
/* Push a new state, which is found in yystate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
#ifdef YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
#endif
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
#ifdef yyoverflow
/* Each stack pointer address is followed by the size of
the data in use in that stack, in bytes. */
yyoverflow("internal error: parser stack overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
#ifdef YYLSP_NEEDED
&yyls1, size * sizeof (*yylsp),
#endif
&yystacksize);
yyss = yyss1; yyvs = yyvs1;
#ifdef YYLSP_NEEDED
yyls = yyls1;
#endif
#else /* no yyoverflow */
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
{
yyerror("internal error: parser stack overflow");
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
__yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
__yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
__yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
#ifdef YYLSP_NEEDED
yylsp = yyls + size - 1;
#endif
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "stack size increased to %d\n", yystacksize);
#endif
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "entering state %d\n", yystate);
#endif
yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (yychar == YYEMPTY)
{
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "reading a token: ");
#endif
yyStackSize = yyssp - (yyss - 1);
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "now at end of input.\n");
#endif
}
else
{
yychar1 = YYTRANSLATE(yychar);
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "next token is %d (%s)\n", yychar, yytname[yychar1]);
#endif
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* count tokens shifted since error; after three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
#if YYDEBUG != 0
if (yydebug)
{
if (yylen == 1)
fprintf (stderr, "reducing 1 value via rule %d (line %d), ",
yyn, yyrline[yyn]);
else
fprintf (stderr, "reducing %d values via rule %d (line %d), ",
yylen, yyn, yyrline[yyn]);
}
#endif
$ /* the action file gets copied in in place of this dollarsign */
//#ln 362 "bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
#ifdef YYLSP_NEEDED
yylsp -= yylen;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#ifdef YYLSP_NEEDED
yylsp++;
if (yylen == 0)
{
yylsp->first_line = yylloc.first_line;
yylsp->first_column = yylloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
#endif
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
++yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
msg = (char *) xmalloc(size + 15);
strcpy(msg, "syntax error");
if (count < 5)
{
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, yytname[x]);
strcat(msg, "'");
count++;
}
}
yyerror(msg);
free(msg);
}
else
#endif /* YYERROR_VERBOSE */
yyerror("syntax error");
}
yyerrlab1: /* here on error raised explicitly by an action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (yychar == YYEOF)
YYABORT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
#ifdef YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "error: state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "shifting error token, ");
#endif
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
}
@@ -0,0 +1,155 @@
%{
#define YYSTYPE double
#include <malloc.h>
#include <memory.h>
#include "Compiler.h"
#include "eval.h"
yyerror(char *);
yylex();
extern int yyStackSize;
extern double result;
int regs[26];
int base;
%}
%token VALUE IDENTIFIER FUNCTION1 FUNCTION2 FUNCTION3
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
%left UPLUS /*supplies precedence for unary plus */
%% /*beginning of rules section */
stat : math_expr
{ $$ = $1; result = $1; }
| IDENTIFIER '=' math_expr
{ if (parseType == PARSE_EVAL)
{
setVar((int)$1, $3);
$$ = $3;
result = $3;
}
else
{
double i = setVar((int)$1, 0);
double v = createCompiledValue(0, &(varTable[(int)i].value));
$$ = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, $3);
result = $$;
}
}
;
value : VALUE { $$ = $1 }
primary_expr
: IDENTIFIER
{ $$ = getVar((int)$1);}
| value
{ $$ = $1;}
| '(' math_expr ')'
{ $$ = $2;}
;
math_expr
: primary_expr
{ $$ = $1; }
| math_expr '*' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 * $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, $1, $3);
}
| math_expr '/' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 / $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, $1, $3);
}
| math_expr '%' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 % (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, $1, $3);
}
| math_expr '+' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 + $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_ADD, $1, $3);
}
| math_expr '-' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 - $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_SUB, $1, $3);
}
| math_expr '&' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 & (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_AND, $1, $3);
}
| math_expr '|' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 | (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_OR, $1, $3);
}
| '-' math_expr %prec UMINUS
{ if (parseType == PARSE_EVAL)
$$ = -$2;
else
$$ = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, $2);
}
| '+' math_expr %prec UPLUS
{ if (parseType == PARSE_EVAL)
$$ = +$2;
else
$$ = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, $2);
}
| fonction
{ $$ = $1; }
;
fonction
: FUNCTION1 '(' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction1((int)$1, $3);
else
$$ = createCompiledFunction1(MATH_FN, (int)$1, $3);
}
| FUNCTION2 '(' math_expr ',' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction2((int)$1, $3, $5);
else
$$ = createCompiledFunction2(MATH_FN, (int)$1, $3, $5);
}
| FUNCTION3 '(' math_expr ',' math_expr ',' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction3((int)$1, $3, $5, $7);
else
$$ = createCompiledFunction3(MATH_FN, (int)$1, $3, $5, $7);
}
;
%%
main()
{
return(yyparse());
}
yywrap()
{
return(1);
}
@@ -0,0 +1,13 @@
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define VALUE 258
#define IDENTIFIER 259
#define FUNCTION1 260
#define FUNCTION2 261
#define FUNCTION3 262
#define UMINUS 263
#define UPLUS 264
extern YYSTYPE yylval;
@@ -0,0 +1,901 @@
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include "Compiler.h"
#include "eval.h"
// these are used by our assembly code
static float g_cmpaddtab[2]={0.0,1.0};
static float g_signs[2]={1.0,-1.0};
static double g_closefact = 0.00001;
static float g_half=0.5;
static float negativezeropointfive=-0.5f;
static float onepointfive=1.5f;
/// functions called by built code
#define SHITCALL __fastcall
#define isnonzero(x) (fabs(x) > g_closefact)
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _rand(double *x)
{
if (*x < 1.0) *x=1.0;
return (double)(rand()%(int)max(*x,1.0));
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _band(double *var, double *var2)
{
return isnonzero(*var) && isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _bor(double *var, double *var2)
{
return isnonzero(*var) || isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _sig(double *x, double *constraint)
{
double t = (1+exp(-*x * (*constraint)));
return isnonzero(t) ? 1.0/t : 0;
}
extern char *g_evallib_visdata;
static double SHITCALL getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
{
int x;
int accum=0;
if (ch && ch != 1 && ch != 2) return 0.0;
if (bw < 1) bw=1;
bc-=bw/2;
if (bc < 0)
{
bw+=bc;
bc=0;
}
if (bc > 575) bc=575;
if (bc+bw > 576) bw=576-bc;
if (!ch)
{
for (x = 0; x < bw; x ++)
{
accum+=(visdata[bc]^xorv)-xorv;
accum+=(visdata[bc+576]^xorv)-xorv;
bc++;
}
return (double)accum / ((double)bw*255.0);
}
else
{
if (ch == 2) visdata+=576;
for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
return (double)accum / ((double)bw*127.5);
}
}
static double SHITCALL getspec_(double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),0)*0.5;
}
static double SHITCALL getosc_(double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata+576*2,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),128);
}
static double SHITCALL gettime_(double *sc)
{
int ispos;
if ((ispos=(*sc > -1.001 && *sc < -0.999)) || (*sc > -2.001 && *sc < -1.999))
{
int pos=0;
extern HWND hwnd_WinampParent;
if (IsWindow(hwnd_WinampParent))
{
if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!ispos,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos)) pos=0;
}
if (!ispos) return (double)pos;
return pos / 1000.0;
}
return GetTickCount()/1000.0 - *sc;
}
static double SHITCALL setmousepos_(double *x, double *y)
{
//fucko: implement me
return 0.0;
}
static double SHITCALL getmouse_(double *which)
{
int w=(int)(*which+0.5);
if (w > 5)
return (GetAsyncKeyState(w)&0x8000)?1.0:0.0;
if (w == 1 || w == 2)
{
double DDraw_translatePoint(POINT p, int isY);
POINT p;
GetCursorPos(&p);
return DDraw_translatePoint(p,w==2);
}
if (w == 3) return (GetAsyncKeyState(MK_LBUTTON)&0x8000)?1.0:0.0;
if (w == 4) return (GetAsyncKeyState(MK_RBUTTON)&0x8000)?1.0:0.0;
if (w == 5) return (GetAsyncKeyState(MK_MBUTTON)&0x8000)?1.0:0.0;
return 0.0;
}
// end functions called by inline code
// these make room on the stack for local variables, but do not need to
// worry about trashing ebp, since none of our code uses ebp and there's
// a pushad+popad surrounding the call
#if 0 // dont seem to need to do this
#define CF_PUSHREGS __asm { push esi } __asm { push edi }
#define CF_POPREGS __asm { pop edi } __asm { pop esi }
#else
#define CF_PUSHREGS
#define CF_POPREGS
#endif
#define FUNC1_ENTER \
double *parm_a, *__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov __nextBlock, esi } \
CF_PUSHREGS
#define FUNC2_ENTER \
double *parm_a,*parm_b,*__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov dword ptr parm_b, ebx } \
__asm { mov __nextBlock, esi } \
CF_PUSHREGS
#define FUNC3_ENTER \
double *parm_a,*parm_b,*parm_c,*__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov dword ptr parm_b, ebx } \
__asm { mov dword ptr parm_c, ecx } \
__asm { mov __nextBlock, esi } \
CF_PUSHREGS
#define FUNC_LEAVE \
__asm { mov eax, esi } \
__asm { add esi, 8 } \
__asm { mov esp, ebp } \
CF_POPREGS
static double (*__asin)(double) = &asin;
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_asin(void)
{
FUNC1_ENTER
*__nextBlock = __asin(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_asin_end(void) {}
static double (*__acos)(double) = &acos;
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_acos(void)
{
FUNC1_ENTER
*__nextBlock = __acos(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_acos_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan)(double) = &atan;
__declspec ( naked ) void _asm_atan(void)
{
FUNC1_ENTER
*__nextBlock = __atan(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_atan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan2)(double,double) = &atan2;
__declspec ( naked ) void _asm_atan2(void)
{
FUNC2_ENTER
*__nextBlock = __atan2(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_atan2_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL * __sig)(double *,double *) = &_sig;
__declspec ( naked ) void _asm_sig(void)
{
FUNC2_ENTER
*__nextBlock = __sig(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_sig_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__rand)(double *) = &_rand;
__declspec ( naked ) void _asm_rand(void)
{
FUNC1_ENTER
*__nextBlock = __rand(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_rand_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__band)(double *,double *) = &_band;
__declspec ( naked ) void _asm_band(void)
{
FUNC2_ENTER
*__nextBlock = __band(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_band_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double ( SHITCALL *__bor)(double *,double *) = &_bor;
__declspec ( naked ) void _asm_bor(void)
{
FUNC2_ENTER
*__nextBlock = __bor(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_bor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (* __pow)(double,double) = &pow;
__declspec ( naked ) void _asm_pow(void)
{
FUNC2_ENTER
*__nextBlock = __pow(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_pow_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__exp)(double) = &exp;
__declspec ( naked ) void _asm_exp(void)
{
FUNC1_ENTER
*__nextBlock = __exp(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_exp_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__floor)(double) = &floor;
__declspec ( naked ) void _asm_floor(void)
{
FUNC1_ENTER
*__nextBlock = __floor(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_floor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__ceil)(double) = &ceil;
__declspec ( naked ) void _asm_ceil(void)
{
FUNC1_ENTER
*__nextBlock = __ceil(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_ceil_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__getosc)(double *,double *,double *) = &getosc_;
__declspec ( naked ) void _asm_getosc(void)
{
FUNC3_ENTER
*__nextBlock = __getosc(parm_c,parm_b,parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getosc_end(void) {}
static double (SHITCALL *__getspec)(double *,double *,double *) = &getspec_;
__declspec ( naked ) void _asm_getspec(void)
{
FUNC3_ENTER
*__nextBlock = __getspec(parm_c,parm_b,parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getspec_end(void) {}
static double (SHITCALL *__gettime)(double *) = &gettime_;
__declspec ( naked ) void _asm_gettime(void)
{
FUNC1_ENTER
*__nextBlock = __gettime(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_gettime_end(void) {}
// do nothing, eh
__declspec ( naked ) void _asm_exec2(void)
{
}
__declspec ( naked ) void _asm_exec2_end(void) { }
static double (SHITCALL *__getmouse)(double *) = &getmouse_;
__declspec ( naked ) void _asm_getmouse(void)
{
FUNC1_ENTER
*__nextBlock = __getmouse(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getmouse_end(void) {}
static double (SHITCALL *__setmousepos)(double *,double *) = &setmousepos_;
__declspec ( naked ) void _asm_setmousepos(void)
{
FUNC2_ENTER
*__nextBlock = __setmousepos(parm_a,parm_b);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_setmousepos_end(void) {}
__declspec ( naked ) void _asm_invsqrt(void)
{
__asm
{
fld qword ptr [eax]
mov edx, 0x5f3759df
fst dword ptr [esi]
// floating point stack has input, as does [eax]
fmul dword ptr [negativezeropointfive]
mov ecx, [esi]
sar ecx, 1
sub edx, ecx
mov [esi], edx
// st(0) = input, [eax] has x
fmul dword ptr [esi]
fmul dword ptr [esi]
fadd dword ptr [onepointfive]
fmul dword ptr [esi]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_invsqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sin(void)
{
__asm
{
fld qword ptr [eax]
fsin
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sin_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_cos(void)
{
__asm
{
fld qword ptr [eax]
fcos
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_cos_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_tan(void)
{
__asm
{
fld qword ptr [eax]
fsincos
fdiv
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_tan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sqr(void)
{
__asm
{
fld qword ptr [eax]
fmul st(0), st(0)
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sqr_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sqrt(void)
{
__asm
{
fld qword ptr [eax]
fabs
fsqrt
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_log(void)
{
__asm
{
fld1
fldl2e
fdiv
fld qword ptr [eax]
mov eax, esi
fyl2x
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_log_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_log10(void)
{
__asm
{
fld1
fldl2t
fdiv
fld qword ptr [eax]
mov eax, esi
fyl2x
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_log10_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_abs(void)
{
__asm
{
fld qword ptr [eax]
fabs
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_abs_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_assign(void)
{
__asm
{
fld qword ptr [eax]
fstp qword ptr [ebx]
}
}
__declspec ( naked ) void _asm_assign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_add(void)
{
__asm
{
fld qword ptr [eax]
fadd qword ptr [ebx]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_add_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sub(void)
{
__asm
{
fld qword ptr [ebx]
fsub qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sub_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_mul(void)
{
__asm
{
fld qword ptr [ebx]
fmul qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_mul_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_div(void)
{
__asm
{
fld qword ptr [ebx]
fdiv qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_div_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_mod(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fsub dword ptr [g_cmpaddtab+4]
fabs
fadd qword ptr [eax]
fadd dword ptr [g_cmpaddtab+4]
fmul dword ptr [g_half]
fistp dword ptr [esi]
fistp dword ptr [esi+4]
mov eax, [esi+4]
xor edx, edx
div dword ptr [esi]
mov [esi], edx
fild dword ptr [esi]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_mod_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_or(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fistp qword ptr [esi]
fistp qword ptr [esi+8]
mov ebx, [esi+8]
or [esi], ebx
mov ebx, [esi+12]
or [esi+4], ebx
fild qword ptr [esi]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_or_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_and(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fistp qword ptr [esi]
fistp qword ptr [esi+8]
mov ebx, [esi+8]
and [esi], ebx
mov ebx, [esi+12]
and [esi+4], ebx
fild qword ptr [esi]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_and_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_uplus(void) // this is the same as doing nothing, it seems
{
#if 0
__asm
{
mov ebx, nextBlock
mov ecx, [eax]
mov [ebx], ecx
mov ecx, [eax+4]
mov [ebx+4], ecx
mov eax, ebx
add ebx, 8
mov nextBlock, ebx
}
#endif
}
__declspec ( naked ) void _asm_uplus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_uminus(void)
{
__asm
{
mov ecx, [eax]
mov ebx, [eax+4]
xor ebx, 0x80000000
mov [esi], ecx
mov [esi+4], ebx
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_uminus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sign(void)
{
__asm
{
mov ecx, [eax+4]
shr ecx, 31
fld dword ptr [g_signs+ecx*4]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_sign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_bnot(void)
{
__asm
{
fld qword ptr [eax]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_bnot_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_if(void)
{
__asm
{
fld qword ptr [eax]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
mov dword ptr [esi], 0FFFFFFFFh
mov dword ptr [esi+4], 0FFFFFFFFh
and eax, (1<<2)
mov eax, [esi+eax]
call eax // call the proper function
// at this point, the return value will be in eax, as desired
}
}
__declspec ( naked ) void _asm_if_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_equal(void)
{
__asm
{
fld qword ptr [eax]
fsub qword ptr [ebx]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_equal_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_below(void)
{
__asm
{
fld qword ptr [ebx]
fcomp qword ptr [eax]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_below_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_above(void)
{
__asm
{
fld qword ptr [eax]
fcomp qword ptr [ebx]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_above_end(void) {}
__declspec ( naked ) void _asm_min(void)
{
__asm
{
fld qword ptr [eax]
fld qword ptr [ebx]
fld st(1)
fsub st(0), st(1)
fabs // stack contains fabs(1-2),1,2
fchs
fadd
fadd
fmul dword ptr [g_half]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_min_end(void) {}
__declspec ( naked ) void _asm_max(void)
{
__asm
{
fld qword ptr [eax]
fld qword ptr [ebx]
fld st(1)
fsub st(0), st(1)
fabs // stack contains fabs(1-2),1,2
fadd
fadd
fmul dword ptr [g_half]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_max_end(void) {}
@@ -0,0 +1,238 @@
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include "cal_tab.h"
#include "compiler.h"
#include "eval.h"
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
int yyparse(char *exp);
void llinit(void);
int gettoken(char *lltb, int lltbsiz);
char yytext[256]="";
char lastVar[256]="";
int *errPtr;
int result;
int colCount=0;
varType *varTable;
char last_error_string[1024];
double globalregs[100];
//------------------------------------------------------------------------------
void *compileExpression(char *exp)
{
int errv=0;
errPtr=&errv;
llinit();
if (!yyparse(exp) && !*errPtr)
{
return (void*)result;
}
return 0;
}
//------------------------------------------------------------------------------
void setLastVar(void)
{
gettoken(lastVar, sizeof lastVar);
}
//------------------------------------------------------------------------------
int setVar(int varNum, double value)
{
int i=varNum;
if (varNum < 0)
{
char *var=lastVar;
if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
{
int x=atoi(var+3);
if (x < 0 || x > 99) x=0;
i=EVAL_MAX_VARS+x;
}
else
{
for (i=0;i<EVAL_MAX_VARS;i++)
{
if (!varTable[i].name[0] || !_strnicmp(varTable[i].name,lastVar,sizeof(varTable[i].name)))
break;
}
if (i==EVAL_MAX_VARS) return -1;
}
}
if (i < 0 || i >= EVAL_MAX_VARS+100)
{
return -1;
}
if (i >= EVAL_MAX_VARS && i < EVAL_MAX_VARS+100)
{
globalregs[i - EVAL_MAX_VARS]=value;
}
else if (!varTable[i].name[0])
{
strncpy(varTable[i].name,lastVar,sizeof(varTable[i].name));
varTable[i].value = value;
}
return i;
}
//------------------------------------------------------------------------------
int getVar(int varNum)
{
if (varNum >= EVAL_MAX_VARS && varNum < EVAL_MAX_VARS+100)
return createCompiledValue(0, globalregs + (varNum - EVAL_MAX_VARS));
if (varNum >= 0 && varNum < EVAL_MAX_VARS)
return createCompiledValue(0, &(varTable[varNum].value));
return createCompiledValue(0, NULL);
}
#if 0
//------------------------------------------------------------------------------
double *getVarPtr(char *var)
{
int i;
if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
{
int x=atoi(var+3);
if (x < 0 || x > 99) x=0;
return globalregs + x;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
return &(varTable[i].value);
return NULL;
}
#endif
//------------------------------------------------------------------------------
double *registerVar(char *var)
{
int i;
if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
{
int x=atoi(var+3);
if (x < 0 || x > 99) x=0;
return globalregs + x;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!varTable[i].name[0] ||
!_strnicmp(varTable[i].name,var,sizeof(varTable[i].name)))
break;
if (i==EVAL_MAX_VARS) return NULL;
if (!varTable[i].name[0])
{
strncpy(varTable[i].name,var,sizeof(varTable[i].name));
varTable[i].value = 0.0;
}
return &(varTable[i].value);
}
//------------------------------------------------------------------------------
int translate(int type)
{
int v;
int n;
*yytext = 0;
gettoken(yytext, sizeof yytext);
switch (type)
{
case INTCONST: return createCompiledValue((double)atoi(yytext), NULL);
case DBLCONST: return createCompiledValue((double)atof(yytext), NULL);
case HEXCONST:
v=0;
n=0;
while (1)
{
int a=yytext[n++];
if (a >= '0' && a <= '9') v+=a-'0';
else if (a >= 'A' && a <= 'F') v+=10+a-'A';
else if (a >= 'a' && a <= 'f') v+=10+a-'a';
else break;
v<<=4;
}
return createCompiledValue((double)v, NULL);
}
return 0;
}
//------------------------------------------------------------------------------
int objectId(int nParams)
{
switch (nParams)
{
case 1: return FUNCTION1;
case 2: return FUNCTION2;
case 3: return FUNCTION3;
}
return IDENTIFIER;
}
//------------------------------------------------------------------------------
int lookup(int *typeOfObject)
{
int i;
gettoken(yytext, sizeof yytext);
if (!_strnicmp(yytext,"reg",3) && strlen(yytext) == 5 && isdigit(yytext[3]) && isdigit(yytext[4]) && (i=atoi(yytext+3))>=0 && i<100)
{
*typeOfObject=IDENTIFIER;
return i+EVAL_MAX_VARS;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
{
*typeOfObject = IDENTIFIER;
return i;
}
for (i=0;getFunctionFromTable(i);i++)
{
functionType *f=getFunctionFromTable(i);
if (!strcmpi(f->name, yytext))
{
*typeOfObject = objectId(f->nParams);
return i;
}
}
*typeOfObject = IDENTIFIER;
setLastVar();
i = setVar(-1, 0);
return i;
}
//---------------------------------------------------------------------------
void count(void)
{
gettoken(yytext, sizeof yytext);
colCount+=strlen(yytext);
}
//---------------------------------------------------------------------------
int yyerror(char *txt)
{
*errPtr = colCount;
return 0;
}
@@ -0,0 +1,41 @@
#ifndef __EVAL_H
#define __EVAL_H
#ifdef __cplusplus
extern "C" {
#endif
// stuff that apps will want to use
#define EVAL_MAX_VARS 256
typedef struct
{
char name[8];
double value;
} varType;
extern double globalregs[100];
extern char last_error_string[1024];
void resetVars(varType *vars);
double *getVarPtr(char *varName);
double *registerVar(char *varName);
// other shat
extern varType *varTable;
extern int *errPtr;
extern int colCount;
extern int result;
int setVar(int varNum, double value);
int getVar(int varNum);
void *compileExpression(char *txt);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1 @@
lex -i scan.l
@@ -0,0 +1,2 @@
bison -d cal.y
@@ -0,0 +1,84 @@
Expression evaluation library v1.0 - by lone
--------------------------------------------
How to use
~~~~~~~~~~
¦ resetVars
-----------
void resetVars(void);
Resets the variables table. It is necessary to call it prior to evaluate your first
expression or variables contents may be random instead of zero
¦ evaluate
----------
double evaluate(char *expression, int *col);
Evaluates an expression and returns the result.
If a syntax error was encountered during the parsing of the expression, then col will
be non-null and col-1 will be the index of the char which triggered the error.
Limitations
~~~~~~~~~~~
¦ you can set only up to 1024 variables.
¦ only decimal and hexadecimal bases available
¦ operators are limited to :
+ - / * % & |
¦ functions are limited to :
sin, cos, tan,
asin, acos, atan,
atan2, sqr, sqrt,
pow, exp, log, log10
Some examples
~~~~~~~~~~~~~
- assignments :
pi=3.1415927
a=atan2(cos(pi/4),2)
- direct evaluations :
cos(pi/4)
sin(45)
- base notations :
3bh (this is 0x3B)
17d (this is 17)
17dh (this is 0x17D)
Adding new functions
~~~~~~~~~~~~~~~~~~~~
The file EVAL.C contains the functions table (fnTable). Just add an entry with the name,
the number of parameters, and a pointer to the function body. Implement the body and
you're done. If your function ahs more than 2 parameters, you'll need to extend the grammar
description file (CAL.Y) to add the FUNCTION3 (and eventually subsequent) token(s) and
parsing informations.
SCAN.L & CAL.Y
~~~~~~~~~~~~~~
SCAN.L contains description for the lexical analyzer generator (LEX). Use makel.bat to rebuild
LEXTAB.C
CAL.Y contains the LALR formal grammar description for the parser generator (BISON). Use makey.bat
to rebuild CAL_TAB.C
Compiling
~~~~~~~~~
Just include all source files to your project, and include EVAL.H into your main source code.
+104
View File
@@ -0,0 +1,104 @@
/*
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 _FF_IPC_H
#define _FF_IPC_H
// -----------------------------------------------------------------------------------------------------
// ----- IPC_FF_GETSKINCOLOR : Ask for a skin color -- the color is filtered for the current theme -----
// -----------------------------------------------------------------------------------------------------
#define IPC_FF_GETSKINCOLOR IPC_FF_FIRST + 1 // data = ff_skincolor struct with .colorname, fills in .color
typedef struct {
char colorname[256];
COLORREF color;
} ff_skincolor;
// List of default colors as of june 30, 2003. see freeform/xml/wasabi/xml/system-colors.xml for latest/complete list
// Trees
#define SKINCOLOR_TREE_ITEMTEXT "wasabi.tree.text"
#define SKINCOLOR_TREE_SELITEMBKG "wasabi.tree.selected"
#define SKINCOLOR_TREE_HILITEDROP "wasabi.tree.hiliteddrop"
// Lists
#define SKINCOLOR_LIST_ITEMTEXT "wasabi.list.text"
#define SKINCOLOR_LIST_SELITEMBKG "wasabi.list.item.selected"
#define SKINCOLOR_LIST_FOCUSITEMBKG "wasabi.list.item.focused"
#define SKINCOLOR_LIST_COLUMNBKG "wasabi.list.column.background"
#define SKINCOLOR_LIST_COLUMNTEXT "wasabi.list.column.text"
#define SKINCOLOR_LIST_SELITEMTEXT "wasabi.list.item.selected.fg"
#define SKINCOLOR_LIST_COLUMNSEPARATOR "wasabi.list.column.separator"
// Buttons
#define SKINCOLOR_BUTTON_TEXT "wasabi.button.text"
#define SKINCOLOR_BUTTON_HILITETEXT "wasabi.button.hiliteText"
#define SKINCOLOR_BUTTON_DIMMEDTEXT "wasabi.button.dimmedText"
// ----------------------------------------------------------------------------------------
// ----- IPC_FF_GENSKINBITMAP: Ask gen_ff to create a bitmap of various skin elements -----
// ----------------------------------------------------------------------------------------
// NOTE: You should free the hbitmap eventually using DeleteObject
#define IPC_FF_GENSKINBITMAP IPC_FF_FIRST + 2 // data = ff_skinbitmap with bitmap .id .w .h and .state, fills in .bitmap
typedef struct {
int id; // see below
int w, h;
int state; // id specific, see below
HBITMAP bitmap;
} ff_skinbitmap;
// Bitmap IDs :
#define SKINBITMAP_BUTTON 0 // Generate a button bitmap. states are as follows :
#define BUTTONSTATE_NORMAL 0
#define BUTTONSTATE_PUSHED 1
#define SKINBITMAP_SCROLLBARUPBUTTON 1 // Generate a scrollbar up button bitmap. states are button states
#define SKINBITMAP_SCROLLBARDOWNBUTTON 2 // Generate a scrollbar down button bitmap. states are button states
#define SKINBITMAP_SCROLLBARLEFTBUTTON 3 // Generate a scrollbar left button bitmap. states are button states
#define SKINBITMAP_SCROLLBARRIGHTBUTTON 4 // Generate a scrollbar right button bitmap. states are button states
#define SKINBITMAP_SCROLLBARVBUTTON 5 // Generate a scrollbar vertical button bitmap. states are button states
#define SKINBITMAP_SCROLLBARHBUTTON 6 // Generate a scrollbar vertical button bitmap. states are button states
// -----------------------------------------------------------------------------------------------
// ----- IPC_FF_ONCOLORTHEMECHANGED: CALLBACK - sent when the skin's color theme has changed -----
// -----------------------------------------------------------------------------------------------
#define IPC_FF_ONCOLORTHEMECHANGED IPC_FF_FIRST + 3 // data = name of the new color theme (const char *)
#define IPC_FF_ISMAINWND IPC_FF_FIRST + 4 // data = hwnd, returns 1 if hwnd is main window or any of its windowshade
#define IPC_FF_GETCONTENTWND IPC_FF_FIRST + 5 // data = HWND, returns the wa2 window that is embedded in the window's container (ie if hwnd is the pledit windowshade hwnd, it returns the wa2 pledit hwnd). if no content is found (ie, the window has nothing embedded) it returns the parameter you gave it
#define IPC_FF_NOTIFYHOTKEY IPC_FF_FIRST + 6 // data = const char * to hotkey description
#endif
@@ -0,0 +1,32 @@
Many AVS effects allow you to write simple expressions to control
visualization. Here is a brief summary of how to write AVS code.
Many aspects of AVS code are similar to C (including comments).
You can create new variables just by using them, and you can read
and write predefined variables (of which each effect has its own)
to interact with the effect. Note that variables are all floating
point numbers (no strings), and the maximum length of a variable's
name is 8 characters (anything longer will be ignored.
So, to create a variable, you can simply use it, for example:
x = 5;
You can also use a variety of operators and math functions to
modify variables, see the Operators and Functions tabs above.
Code can include C and C++ style comments:
// using the doubleslash comments until the end of the line
/* using the classic C comments
comment a block of text */
You can combine operators and functions into expressions, such
as:
x = 5 * cos(y) / 32.0; // this does some leetness right here
You can use multiple expressions by seperating them with one or
more semicolons, for example:
x = x * 17.0; x = x / 5; y = pow(x,3.0);
It is worth noting that extra whitespace (spaces, newlines) is
ignored, so if you need to space things out for clarity, you can.
@@ -0,0 +1,32 @@
The following operators are available:
=
assigns a value to a variable.
example: var=5;
+
adds two values, returns the sum.
example: var=5+var2;
-
subtracts two values, returns the difference.
example: var=5-var2;
*
multiplies two values, returns the product.
example: var=5*var2;
/
divides two values, returns the quotient.
example: var=5/var2;
%
converts two values to integer, performs division, returns remainder
example: var=var2%5;
|
converts two values to integer, returns bitwise OR of both values
example: var=var2|31;
&
converts two values to integer, returns bitwise AND of both values
example: var=var2&31;
@@ -0,0 +1,133 @@
Functions available from code:
abs(value)
= returns the absolute value of 'value'
sin(value)
= returns the sine of the radian angle 'value'
cos(value)
= returns the cosine of the radian angle 'value'
tan(value)
= returns the tangent of the radian angle 'value'
asin(value)
= returns the arcsine (in radians) of 'value'
acos(value)
= returns the arccosine (in radians) of 'value'
atan(value)
= returns the arctangent (in radians) of 'value'
atan2(value,value2)
= returns the arctangent (in radians) of 'value'/'value2'
sqr(value)
= returns the square of 'value'
sqrt(value)
= returns the square root of 'value'
invsqrt(value)
= returns the reciprocal of the square root of 'value' (1/sqrt(value))
(uses a fast approximation, may not always = 1/sqrt(value) :)
pow(value,value2)
= returns 'value' to the power of 'value2'
exp(value)
= returns e to the power of 'value'
log(value)
= returns the log in base e of 'value'
log10(value)
= returns the log in base 10 of 'value'
floor(value)
= returns the largest integer less than or equal to 'value'
ceil(value)
= returns the smallest integer greater than or equal to 'value'
"sign(value)
= returns the sign of 'value' (-1.0 or 1.0, or 0.0 or -0.0 for 0.0 or -0.0)
"min(value,value2)
= returns the smallest of 'value' and 'value2'
"max(var,var2)
= returns the greatest of 'value' and 'value2'
"sigmoid(value,value2)
= returns sigmoid function value of x='value' ('value2'=constraint)
"rand(value)
= returns a random integer between 0 and 'value'
"band(value,value2)
= returns a boolean AND of 'value' and 'value2'
"bor(value,value2)
= returns a boolean OR of 'value' and 'value2'
"bnot(value)
= returns a boolean NOT of 'value'
"if(condition,valtrue,valfalse)
= returns 'valtrue' if 'condition' is nonzero, returns 'valfalse' otherwise.
new in AVS 2.8+: only one of valtrue/valfalse is evaluated, depending on condition
"assign(dest, source)
= if 'dest' is a variable, assigns the value of 'source' to it. returns the value of 'source'.
a little trick: assign(if(v,a,b),1.0); is like if V is true, a=1.0, otherwise b=1.0. :)
"exec2(parm1, parm2)
= evaluates parm1, then parm2, and returns the value of parm2.
"equal(value,value2)
= returns 1.0 if 'value' is equal to 'value2', otherwise returns 0.0
"above(value,value2)
= returns 1.0 if 'value' is greater than 'value2', otherwise returns 0.0
"below(value,value2)
= returns 1.0 if 'value' is less than 'value2', otherwise returns 0.0
"getosc(band,width,channel)
= returns waveform data centered at 'band', (0..1), sampled 'width' (0..1) wide.
'channel' can be: 0=center, 1=left, 2=right. return value is (-1..1)
"getspec(band,width,channel)
= returns spectrum data centered at 'band', (0..1), sampled 'width' (0..1) wide.
'channel' can be: 0=center, 1=left, 2=right. return value is (0..1)
gettime(start_time)
= returns time in seconds since start_time (start_time can be 0 for time since boot)
(start_time can be -1.0 for current play time in seconds
(start_time can be -2.0 for current play length in seconds
getkbmouse(which_parm)
= returns information about the location and state of the keyboard or mouse
which_parm = 1: mouse X position (-1..1 is onscreen)
which_parm = 2: mouse Y position (-1..1 is onscreen)
which_parm = 3: mouse left button state (0 up, 1 down)
which_parm = 4: mouse right button state (0 up, 1 down)
which_parm = 5: mouse middle button state (0 up, 1 down)
which_parm > 5: (GetAsyncKeyState(which_parm)&0x8000)?1:0
megabuf(index)
= can be used to get or set an item from the 1 million item temp buffer
to get, use: val=megabuf(index);
to set, use: assign(megabuf(index),val);
gmegabuf(index)
= can be used to get or set an item from the global 1 million item buffer
to get, use: val=gmegabuf(index);
to set, use: assign(gmegabuf(index),val);
loop(count, statement)
= executes <statement> <count> times. count is evaluated once and clamped
to 0..4096. best used with exec2() and exec3() and assign(). Note that
the return value of loop() is undefined and should not be used.
@@ -0,0 +1,6 @@
Constants
'$PI' can be used in place of '3.14159'
'$E' can be used in place of '2.71828'
'$PHI' can be used in place of '1.618033'
Numbers can be specified as integers or as floating point
(i.e. '5' or '5.0' or '5.00001')
@@ -0,0 +1,964 @@
/*
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.
*/
#define LDDLL_PREFIX
/*************************************************************************
* Helpful Stuff *
**************************************************************************/
/*
This header file defines a prefix. This is used by C++ programs to append a prefix to the definitions.
For C programs that use the LD2000.H file and associated library, use the following
#define LDDLL_PREFIX //Define the prefix in LD2000.H file as nothing
#include "ld2000.h"
For C++ programs, use the following
#define LDDLL_PREFIX extern "C" //Define the prefix in LD2000.H file as extern "C" to indicate that the names in the lib file have not been mangled
#include "ld2000.h"
*/
/*************************************************************************
* Error Codes *
**************************************************************************/
#define LDERR_OK 0 //Normal Return value
//********** These can occur at any time except InitialQMCheck ****
#define LDERR_FIFO_READ_ERROR -1 //Fifo read zero or non even number of bytes
#define LDERR_QM32_SOFTWARE_ERROR -2 //QM32 is not responding properly
//********** These are reported by the loaders including LoadPalette
#define LDERR_X29_LOADED -11 //File load Successful Return
#define LDERR_LDA_LOADED -12 //values
#define LDERR_ILDA_LOADED -13
#define LDERR_DEC3_LOADED -14
#define LDERR_LDB_LOADED -15
#define LDERR_LDSECURE_LOADED -16
//********* Returned by ConvertToPointFrame **************
#define LDERR_ALREADY_POINT_ORIENTED -31 //Incase somebody tries to
//create a point oriented frame
//from a point oriented frame
//******** Currently only returned by CheckSession **************
#define LDERR_NO_SESSION_IN_PROG -101 //CheckSession return value
//******** Returned by LFileRequest and LPaletteRequest *********
#define LDERR_FILE_REQUEST_CANCEL -201 //File Requestor Cancelled
//********* Returned by file functions **************************
#define LDERR_FILE_NOT_FOUND -401 //Loader errors
#define LDERR_WRONG_FILE_TYPE -402
#define LDERR_DISK_FULL -403
#define LDERR_DISK_WRITE_PROTECTED -404
#define LDERR_FILE_WRITE_PROTECTED -405
#define LDERR_MISC_FILE_ERROR -406
#define LDERR_STRING_TOO_LONG -407 //Supplied filename is over 128 chars in length
//*********** Returned by frame commands such as DisplayFrame ***
#define LDERR_FRAME_OUT_OF_RANGE -501 //Misc programming or config errors
//*********** Returned by point commands such as writepoint *****
#define LDERR_POINT_OUT_OF_RANGE -502
//*********** Returned by show control commands *****************
#define LDERR_TDC_NOT_FOUND -511
#define LDERR_TRANSITION_NOT_FOUND -512
#define LDERR_EFFECT_NOT_FOUND -513
#define LDERR_SCENE_NOT_FOUND -514
#define LDERR_MODULE_NOT_FOUND -515
#define LDERR_SHOW_NOT_FOUND -516
#define LDERR_STRUCTURE_NOT_FOUND -519
//Once the element has been deleted, this will be returned
#define LDERR_EFFECT_DELETED -530
#define LDERR_SCENE_DELETED -531
#define LDERR_MODULE_DELETED -532
#define LDERR_SHOW_DELETED -533
#define LDERR_STRUCTURE_DELETED -539
//If you try to delete something which is inuse one of these will be returned
#define LDERR_EFFECT_INUSE -540
#define LDERR_SCENE_INUSE -541
#define LDERR_MODULE_INUSE -542
#define LDERR_SHOW_INUSE -543
#define LDERR_STRUCTURE_INUSE -549
//*********** These should be rare indeed ***********************
#define LDERR_NO_IBM_MEMORY -601 //No free IBM Memory
#define LDERR_CANT_OPEN_WINDOW -602 //Can't open Window (Debug, FileRequest)
//*********** Alot of commands can return this one **************
#define LDERR_NO_QM32_MEMORY -702 //No free QM32 Memory
//*********** Ran out of memory while trying to load a file *****
#define LDERR_FILE_TOO_LARGE -703 //No free QM32 Memory to load frames
//********** Several unimplemented DLL commands return this *****
#define LDERR_NOT_IMPLEMENTED -801 //DLL Command not implemented
//*** This indicates a timeout during a long communication with the QM32
//*** This only occurs during file loading and saving and ActiveArray functions
#define LDERR_QM32_ERROR -901 //QM32 Communication error
//***** These should only be returned by InitialQMCheck *********
#define LDERR_QM32_NOT_PRESENT -1001 //QM32 is not present (like it sounds)
#define LDERR_QM32_ADDRESS_CONFLICT -1002 //QM32 is not responding properly
#define LDERR_QM32_INITIALIZATION_ERROR -1003 //Same as above, but even weirder
/*************************************************************************
* QM32 Error Codes *
**************************************************************************/
//*** This is a sure sign of QM32 hardware trouble
#define QM32ERROR_NullCommand 1
//*** Usually because of no laser code running in the QM32 but could
//*** be caused by a DLL / Q32 mismatch.
#define QM32ERROR_UndefinedCommand 2
//*** Should only occur during BeginSession. This indicates that a
//*** communications error has occured while loading the file LD.Q32
#define QM32ERROR_DownloadBad 3
#define QM32ERROR_ChecksumBad 4
//*** This is usually caused by a DLL / Q32 mismatch. If it happens
//*** inconsistantly then this could be a sign of QM32 hardware trouble
#define QM32ERROR_Insufficient 5
//*** When the QM32 is reset it does 3 ram tests. If one of them fails, this
//*** would be returned. This is a sign of QM32 hardware trouble.
#define QM32ERROR_DramTestBad 6
//*** If somebody tampers with the rom chip, this would be returned. Actually
//*** nothing may be returned because the QM32 would probably lock up.
#define QM32ERROR_RomTestBad 7
//*** This is equivalent to the Amiga's GURU meditation. It occurs when some
//*** kind of QM32 software violates the system. (divide by zero, access to memory that isn't there, etc.)
//*** In certain circomstances, it may also be caused by a hardware problem.
#define QM32ERROR_AccessError 8
//***************************************************************************
// Flags used by RedrawFrameFast and other things *
//***************************************************************************
#define RFF_NOBLIT 64 //RedrawFrameFast should not copy the bitmap to the screen
#define RFF_NOINITMINMAX 128 //RedrawFrameFast should not init Min and Max variables to 0
#define RFF_DOUBLEBUFFER 2048 //RedrawFrameFast should use double buffering
#define RFF_WHITEDOT 8192 //RedrawFrame should place a white dot at the first point
#define RFF_MONITORPZ 32768 //RedrawFrame should use the laser coordinates from the monitor buffer and not the laser coordinates
#define RFF_GRAYBLANKING 65536 //Show blanking lines as gray lines
#define RFF_SELECTEDZONES 131072 //Show only the selected zones, supplied in the Frame parameter of RedrawFrameFast
//***************************************************************************
// Flags used by DisplayUpdateEx and sometimes by PlayShowEx *
//***************************************************************************
#define DU_LASEROUTPUT 1 //DisplayUpdate should show laser output
#define DU_BEGINSLEW 16 //DisplayUpdate should slew beginning blanked points leading up to the first track
#define DU_CUTSCAN 256 //DisplayUpdate should immediately stop scanning buffer and start a new buffer
/**************************************************************************
* Structures *
***************************************************************************/
typedef struct tagDMXCHANNELMAP{
LONG Function;
SHORT SlewRate;
SHORT Mode;
LONG Reserved1;
LONG Reserved2;
LONG Reserved3;
LONG StartupSource;
LONG StartupValue;
LONG ShutdownSource;
LONG ShutdownValue;
LONG ESTOPSource;
LONG ESTOPValue;
LONG DeselectedSource;
LONG DeselectedValue;
LONG Source;
LONG Value;
LONG STMin;
LONG DMXMin;
LONG STMax;
LONG DMXMax;
LONG STOrigin;
LONG STExtent;
LONG DMXOrigin;
LONG DMXExtent;
LONG DMXExtentOV2;
} DMXCHANNELMAP;
typedef struct tagDMXMAP{
SHORT Reserved1;
SHORT NumChannels;
SHORT Reserved2;
SHORT StartingChannel;
SHORT Reserved3;
SHORT DeviceType;
SHORT Reserved4;
SHORT Nondisplayed;
} DMXMAP;
typedef struct tagPROJECTIONZONE{
LONG Scanner; //Scanner for output
LONG XSize; //Geometric Correction variable -- X Size
LONG YSize; //Geometric Correction variable -- Y Size
LONG XPosition; //Geometric Correction variable -- X Position
LONG YPosition; //Geometric Correction variable -- Y Position
LONG ZRotation; //Geometric Correction variable -- Z Rotation angle
LONG XLinearity; //Geometric Correction variable -- X Linearity
LONG YLinearity; //Geometric Correction variable -- Y Linearity
LONG XKeystone; //Geometric Correction variable -- X Keystone
LONG YKeystone; //Geometric Correction variable -- Y Keystone
//10
LONG XPincussion; //Geometric Correction variable -- X Pin
LONG YPincussion; //Geometric Correction variable -- Y Pin
LONG XPincussionOffset; //Geometric Correction variable -- X Pin Offset
LONG YPincussionOffset; //Geometric Correction variable -- Y Pin Offset
LONG XBow; //Geometric Correction variable -- X Bow
LONG YBow; //Geometric Correction variable -- Y Bow
LONG XBowOffset; //Geometric Correction variable -- X Bow Offset
LONG YBowOffset; //Geometric Correction variable -- Y Bow Offset
LONG XShear; //Geometric Correction variable -- X Shear
LONG YShear; //Geometric Correction variable -- Y Shear
//20
LONG XSymmetry; //Geometric Correction variable -- X Symmetry
LONG YSymmetry; //Geometric Correction variable -- Y Symmetry
LONG Reserved1; //Geometric Correction variable -- Reserved for future use
LONG Reserved2; //Geometric Correction variable -- Reserved for future use
LONG NoMinimumPointsFlag; //BOOL: Don't require minimum points during DisplayUpdate
LONG AllowManipulationsFlag; //BOOL: Allow Scale, Rotate, Position, Perspective and other effects.
LONG AllowMasterResizeFlag; //BOOL: Allow the master size and position controls to affect this projection zone
LONG UseGeometricCorrectionData; //BOOL: Observe geometric correction data when calculating beam position
LONG PreviewWindowXSize; //X Size of the image drawn on the preview window
LONG PreviewWindowYSize; //Y Size of the image drawn on the preview window
//30
LONG PreviewWindowXPosition; //X Position of the image drawn on the preview window
LONG PreviewWindowYPosition; //Y Position of the image drawn on the preview window
LONG PreviewWindowXProjectorPosition; //X Position of the center of all of the beam lines
LONG PreviewWindowYProjectorPosition; //Y Position of the center of all of the beam lines
LONG PreviewWindowMirrorXOutput; //BOOL: Produce a duplicate output with mirrored X output
LONG PreviewWindowMirrorXProjector; //BOOL: Produce a duplicate output with mirrored X position
LONG PreviewWindowShowAsBeamsFlag; //BOOL: When drawing on the preview window, show this as beams
LONG ScannerOptimizer; //BOOL: Optimize blanking path within this projection zone
LONG UseProtectionData; //BOOL: Observe protection data when calculating brightness
LONG Reserved7; //Reserved for future use
//40 long words = 160 bytes
LONG Reserved8; //Reserved for future use
LONG Reserved9;
LONG Reserved10;
LONG Reserved11;
LONG Reserved12;
char Name[24]; //40 byte name field
char Reserved200[200]; //200 reserved bytes
short GeometricCorrectionData[8450]; //65*65*2 integers for geometric correction
char ProtectionZoneData[4096]; //64*64=4096 bytes for protection zone bitmap
} PROJECTIONZONE;
typedef struct tagCOLORREGSTRUCT{
LONG ColorIndex;
LONG RedScreenVal;
LONG GreenScreenVal;
LONG BlueScreenVal;
LONG RedLaserVal;
LONG GreenLaserVal;
LONG BlueLaserVal;
LONG DeepBlueLaserVal;
LONG YellowLaserVal;
LONG FocusLaserVal;
LONG IntensityLaserVal;
LONG ShutterLaserVal;
} COLORREGSTRUCT;
typedef struct tagPTSTRUCT{
LONG XCoord;
LONG YCoord;
LONG ZCoord;
LONG FCoord;
LONG RGBValue;
LONG X3DCoord;
LONG Y3DCoord;
LONG Group;
LONG Status;
} PTSTRUCT;
typedef struct tagFRAMESTRUCT{
LONG VOFlag;
LONG ScanRateMultiplier;
LONG AbstractFlag;
LONG NumPoints;
char FrameNote[24];
} FRAMESTRUCT;
typedef struct tagFRAMESTRUCTEX{
LONG ChangedFlag; //Indicates that this frame has changed since the last time it was saved. This is read-only.
LONG ThreeDFlag; //Indicates that this frame is stored internally as 3D data. This is read-only.
LONG BeamBrushFlag; //Indicates that this frame stores beam brush points internally. This is read-only.
LONG VectorFlag; //Indicates that this frame is to be rendered using the vector renderer. This is read/write.
LONG AbstractFlag; //Indicates that this frame has additional abstract information and that this should be rendered as an abstract.
LONG DMXFlag; //Indicates that this frame has DMX data in addition to point and perhaps abstract data.
LONG RasterFlag; //Indicates that this frame is a raster frame. No special internal handling is done at this time.
LONG MaxRenderedFlag; //Indicates that this frame was rendered by 3D Studio MAX.
LONG SecureFrameFlag; //Indicates that this frame is secured.
LONG Reserved3; //Reserved for future use
LONG PreferredPalette; //Palette that this frame will use unless overridden by Track.
LONG PreferredProjectionZone; //Projection zone that this frame will be projected onto unless overridden by track.
LONG AnimationCount; //Number of frames to the end of the animation. Range is 0 to 65535.
LONG ClipartClass; //Number, usually bit-encoded, that describes the frame. This is only 16-bits internally.
LONG ScanRate; //Scan rate for this frame. If positive, handled as a multiplier. If negative, treated as exact sample rate in 1K increments.
LONG NumPoints; //Number of data points in this frame.
char FrameNote[24]; //23 character, plus null, frame note.
} FRAMESTRUCTEX;
//*************************************************************************
//* Constants
//*************************************************************************
#define frontview 1
#define topview 2
#define sideview 3
#define threeDview 4
#define BLACK RGB(0,0,0)
#define DARKGRAY RGB(128,128,128)
#define LIGHTGRAY RGB(192,192,192)
#define WHITE RGB(255, 255, 255)
//**********************************************************************************
// LD2000.DLL API Functions
//**********************************************************************************
//-------------------------------------------------------------------------------------------
// LD Comm Window Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI OpenLDCommWindow(void);
LDDLL_PREFIX LONG WINAPI CloseLDCommWindow(void);
LDDLL_PREFIX LONG WINAPI WriteToLDCommWindow(LPSTR SUPPLY_OutputString);
LDDLL_PREFIX LONG WINAPI QM32BeepOnError(LONG OnOff); //Controls whether or not the Comm window automatically opens
//--------------------------------------------------------------------------------------------
// Port functions. Only used in the Interactive Character project.
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX unsigned short WINAPI ldInp(unsigned short PortID);
LDDLL_PREFIX unsigned short WINAPI ldInpw(unsigned short PortID);
LDDLL_PREFIX unsigned short WINAPI ldOutp(unsigned short PortID, short DataByte);
LDDLL_PREFIX unsigned short WINAPI ldOutpw(unsigned short PortID, unsigned short DataWord);
//--------------------------------------------------------------------------------------------
// Status and setting and retrieval
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI GetLDStatus(LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI GetDates(LPLONG RETURN_DLLDate, LPLONG RETURN_LibDate, LPLONG RETURN_RomDate);
LDDLL_PREFIX LONG WINAPI GetSerialNumber(LPLONG RETURN_SerialNumber);
//------------------------------------------------------------------------------------------
// QuadMod and session functions
//------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI GetLDDLLModuleUsage(LPLONG ModuleUsage);
LDDLL_PREFIX LONG WINAPI QM32AvailMemEx(LPLONG RETURN_TotalMemory, LPLONG RETURN_TotalFreeMemory, LPLONG RETURN_LargestBlock, LPLONG RETURN_NumFreeBlocks);
LDDLL_PREFIX LONG WINAPI QM32DefragmentMem(LPLONG RETURN_NumBlocksCombined);
LDDLL_PREFIX LONG WINAPI RebootQM32(void);
LDDLL_PREFIX LONG WINAPI InitialQMCheck(LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI BeginSession(LONG MaxFrames, LONG MaxPoints, LONG MaxBuffer, LONG UndoFrames, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI CheckSession(LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI CheckSessionSettings(LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI EndSession(void);
LDDLL_PREFIX LONG WINAPI BeginSessionEx(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
//Does everything necessary to start a session including checking settings and loading parameters from INI file including palette and geometric correction data
//------------------------------------------------------------------------------------------
// Working Scanners, Tracks, Frames
//------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI SetWorkingScanners(LONG Scanner);
LDDLL_PREFIX LONG WINAPI GetWorkingScanners(LONG *RETURN_ScannerSelection);
LDDLL_PREFIX LONG WINAPI SetWorkingTracks(LONG Track);
LDDLL_PREFIX LONG WINAPI SetWorkingFrame(LONG FrameNumber);
LDDLL_PREFIX LONG WINAPI GetWorkingFrame(LPLONG RETURN_Frame);
//-------------------------------------------------------------------------------------------
// Projection Zone Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI ReadProjectionZone(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ);
LDDLL_PREFIX LONG WriteProjectionZone(LONG ZoneNumber, PROJECTIONZONE *SUPPLY_PZ);
LDDLL_PREFIX LONG WINAPI LoadProjectionZones(LPSTR ZoneFilename, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SaveProjectionZones(LPSTR ZoneFilename, LPLONG RETURN_LDStatus);
//-----------------------------------------------------------------------------------------
// Showtime Synchronization Functions
//-----------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI QM32MultiCommand(LONG Allow);
LDDLL_PREFIX LONG WINAPI SetSyncParameters(LONG Proportional, LONG Integral, LONG Derivative);
LDDLL_PREFIX LONG WINAPI SendSync(LONG CurrentTime);
LDDLL_PREFIX LONG WINAPI SendMultiSync(LONG CurrentTime);
LDDLL_PREFIX LONG WINAPI GetShowTimeMilliseconds(LPLONG RETURN_CurrentTime);
LDDLL_PREFIX LONG WINAPI GetQMEvents(LPLONG RETURN_nEvents, LPSTR RETURN_MIDIEventStruct);
LDDLL_PREFIX LONG WINAPI SendSyncGetQMEvents(LONG CurrentTime, LPLONG RETURN_nEvents, LPSTR RETURN_MIDIEventStruct);
//--------------------------------------------------------------------------------------------
// Showtime operation functions
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI SetResetTTL(LONG IOMask, LONG OutputData); //This may go away
LDDLL_PREFIX LONG WINAPI PlayShowEx(LONG StartTime, LONG EndTime, LONG PlaySpeed, LONG Mode);
LDDLL_PREFIX LONG WINAPI StopShow(void); //Correct way to stop a show in progress.
LDDLL_PREFIX LONG WINAPI StopShowEx(LONG Mode); //Mode parameter allows you to skip the final refresh after PlayShow has ended.
//--------------------------------------------------------------------------------------------
// Showtime file functions
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI LoadShowStructures(LPSTR Filename, LONG StructureTypes, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SaveShowStructures(LPSTR Filename, LONG StructureTypes, LPINT RETURN_LDStatus);
//--------------------------------------------------------------------------------------------
// Laser Display Functions
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI ResetLD(void); //Updates all track variables
LONG WINAPI DisplayGeometricCorrection( long Enable, long YLine, short *GeometryData); //GeometryData must be in device coordinates
LDDLL_PREFIX LONG WINAPI DisplaySize( float XSize, float YSize, float ZSize, float CSize, float FSize); // Normalized Variables
LDDLL_PREFIX LONG WINAPI DisplayPosition( float XPosition, float YPosition ); // Normalized Variables
LDDLL_PREFIX LONG WINAPI DisplayAuxOutput(float OutputVoltage);
LDDLL_PREFIX LONG WINAPI lsDisplayAuxOutput(float OutputVoltage, float ZSize, float ZOffset);
LDDLL_PREFIX LONG WINAPI DisplayMasterAngle(float XAngle, float YAngle, float ZAngle); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayFreq3(long PointFreq, long VectorFreq, long AbstractFreq, LPLONG RETURN_ActualPointFreq, LPLONG RETURN_ActualVectorFreq, LPLONG RETURN_ActualAbstractFreq);
LDDLL_PREFIX LONG WINAPI DisplayScanLimits(LONG FromPt, LONG ToPt);
LDDLL_PREFIX LONG WINAPI DisplayObjectSettings(LONG VisibleBeginEmph, LONG VisibleMiddleEmph,
LONG VisibleEndEmph, LONG VisibleDensity,
LONG BlankedBeginEmph, LONG BlankedEndEmph,
LONG BlankedDensity);
LDDLL_PREFIX LONG WINAPI DisplayAbstractSettings(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
LDDLL_PREFIX LONG WINAPI DisplayFlags(LONG Flags);
LDDLL_PREFIX LONG WINAPI SetGetDisplayFlags(LONG Mode, LONG TrackNumber, LPLONG RETURN_Flags);
LDDLL_PREFIX LONG WINAPI DisplayMaskFlags(LONG MaskFlags);
LDDLL_PREFIX LONG WINAPI DisplayScale(float XScale, float YScale, float ZScale); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayRotCenter(float XRotCent, float YRotCent, float ZRotCent); // Normalized
LDDLL_PREFIX LONG WINAPI DisplayAngle(float XAngle, float YAngle, float ZAngle); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayAngleDegrees(float XAngle, float YAngle, float ZAngle); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayRotOrder(LONG RotationOrder);
LDDLL_PREFIX LONG WINAPI DisplayWAngle(float XAngle, float YAngle, float ZAngle); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayWAngleDegrees(float XAngle, float YAngle, float ZAngle); //Normalized
LDDLL_PREFIX LONG WINAPI AutoRotateInit(float InitialXAngle, float InitialYAngle,
float InitialZAngle, LONG AnimateFromFrame,
LONG AnimateToFrame, long AutoRotateTrack);
LDDLL_PREFIX LONG WINAPI AutoRotateIncrement(float XIncrement, float YIncrement, float ZIncrement, LONG TenthFlag);
LDDLL_PREFIX LONG WINAPI AutoRotatePlus(LONG Rotate, LONG GenerateAbstract, LONG Animate, LONG Extra); //Pretty much unneccessary now
LDDLL_PREFIX LONG WINAPI DisplayPostTrans(float XOffs, float YOffs, float ZOffs); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayStereoSettings(float EyeSeparation, long EndOfScanDelay,
float StereoIDLEVoltage, float StereoLEFTVoltage, float StereoRIGHTVoltage); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayPerspective(float Dist, float Xobs, float Yobs, float Zobs);//Norm
LDDLL_PREFIX LONG WINAPI DisplayWindow( float WinLeft,
float WinRight, float WinBottom, float WinTop,
float WinRear, float WinFront); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayWindowX(float WinLeft, float WinRight); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayWindowY(float WinBot, float WinTop); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayWindowZ(float WinRear, float WinFront); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayCSize(float ColorSize); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayPaletteSelect(LONG Palette1, LONG Palette2);
LDDLL_PREFIX LONG WINAPI DisplayPaletteMix(float MixValue); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayHueOffset(LONG HueStart, LONG HueEnd, LONG HueNew);
LDDLL_PREFIX LONG WINAPI DisplaySaturation(float SaturationLevel); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayPath(LONG Frame, LONG Point);
LDDLL_PREFIX LONG WINAPI DisplayIris(float IrisLevel); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayColorWheel(float ColorWheelLevel); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayGoboWheel(float Gobo1, float Gobo2, float Gobo3); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayGoboRotate(float Gobo1, float Gobo2, float Gobo3); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayFrost(float Frost1, float Frost2, float Frost3); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayFocus(float FocusLevel); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayMiscControl(float M1, float M2, float M3); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayDepthCue(float DepthEffect, float MinimumZ, float MaximumZ); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayTrackAllow(long Permission);
LDDLL_PREFIX LONG WINAPI DisplayProjectionZones(long ProjectionZoneCode);
LDDLL_PREFIX LONG WINAPI SetGetDisplayProjectionZones(LONG Mode, LONG TrackNumber, LPLONG RETURN_ProjectionZoneCode);
LDDLL_PREFIX LONG WINAPI DisplayFrame(LONG Frame);
LDDLL_PREFIX LONG WINAPI SetGetDisplayFrame(LONG Mode, LONG TrackNumber, LPLONG RETURN_FrameNumber);
LDDLL_PREFIX LONG WINAPI DisplayFrameMix(LONG ToFrame, float MixValue); //Normalized
LDDLL_PREFIX LONG WINAPI DisplayPreTrans( float XOffs, float YOffs, float ZOffs); //Normalized
LDDLL_PREFIX LONG WINAPI DisplaySkew(LONG TrackDelay, LONG ColorShift, LONG FocusShift);
LDDLL_PREFIX LONG WINAPI DisplayMinimumPoints(LONG MinimumPoints);
LDDLL_PREFIX LONG WINAPI DisplayUpdateTest(void);
LONG WINAPI DisplayBufferStatus(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints);
LDDLL_PREFIX LONG WINAPI DisplayUpdate(void);
LDDLL_PREFIX LONG WINAPI DisplayUpdateToFrame(LONG Frame);
LDDLL_PREFIX LONG WINAPI DisplayUpdateEx(LONG Mode);
LDDLL_PREFIX LONG WINAPI DisplayUpdateMode(LONG SyncMode, LONG LeftRightUpdate);
//--------------------------------------------------------------------------------------------
// QuadMod DMX-512 functions
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI QMDMXMode(LONG DMXMode, LONG TransmitBreakLength, LONG TransmitMABLength, LONG TransmitStartCode, LONG TransmitNumChannels, LONG TransmitRestLength);
LDDLL_PREFIX LONG WINAPI QMDMXInput(LONG ChannelNumber, LPLONG RETURN_Data);
LDDLL_PREFIX LONG WINAPI QMDMXOutput(LONG ChannelNumber, LONG Data);
LDDLL_PREFIX LONG WINAPI QMDMXVirtualChannels(LONG PortAStartChannel, LONG PortBStartChannel, LONG AUXOutChannel, LONG GraphicsShutterChannel);
LDDLL_PREFIX LONG WINAPI QMDMXStartupFrame(LONG Frame);
LDDLL_PREFIX LONG WINAPI QMDMXShutdownFrame(LONG Frame);
LDDLL_PREFIX LONG WINAPI QMDMXESTOP(void);
LDDLL_PREFIX LONG WINAPI DMXToFrame(void);
LDDLL_PREFIX LONG WINAPI FrameToDMX(void);
LDDLL_PREFIX LONG WINAPI GetDMXMap(DMXMAP *RETURN_DMXMap);
LDDLL_PREFIX LONG WINAPI SetDMXMap(DMXMAP *SUPPLY_DMXMap);
LDDLL_PREFIX LONG WINAPI GetDMXChannelMap(LONG ChannelNumber, DMXCHANNELMAP *RETURN_DMXChannel);
LDDLL_PREFIX LONG WINAPI SetDMXChannelMap(LONG ChannelNumber, DMXCHANNELMAP *SUPPLY_DMXChannel);
//-------------------------------------------------------------------------------------------
// Frame Loading and Saving
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI LoadLDA(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr,LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI LoadLDB(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI LoadLDSecure(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI LoadLFile(LPSTR Filename, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI ReadFileInfo(LPSTR Filename, LPSTR RETURN_Description, LPLONG RETURN_NumFrames, LPLONG RETURN_Format, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SaveLFile(LPSTR Filename, LPSTR Description, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPLONG Format, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
//-------------------------------------------------------------------------------------------
// Frame Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI FindFrame(LPSTR Frame, LPLONG RETURN_FrameNumber);
LDDLL_PREFIX LONG WINAPI ReadMaskData(LONG TrackNumber, LONG FAR* RETURN_MaskData);
LDDLL_PREFIX LONG WINAPI SetChangedFlag(LONG FrameNumber, LONG State);
LDDLL_PREFIX LONG WINAPI ReadFrameStruct(LONG FrameNumber, FRAMESTRUCT *RETURN_FrameStruct);
LDDLL_PREFIX LONG WINAPI ReadFrameStructEx(LONG FrameNumber, FRAMESTRUCTEX *RETURN_FrameStructEx);
LDDLL_PREFIX LONG WINAPI WriteFrameStructEx(LONG FrameNumber,FRAMESTRUCTEX *SUPPLY_FrameStructEx);
LDDLL_PREFIX LONG WINAPI ReadFrame(FRAMESTRUCT *RETURN_FrameStruct, PTSTRUCT *RETURN_PointArray);
LDDLL_PREFIX LONG WINAPI WriteFrame(FRAMESTRUCT *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray);
LDDLL_PREFIX LONG WINAPI WriteFrameEx(FRAMESTRUCTEX *SUPPLY_FrameStructEx, PTSTRUCT *SUPPLY_PointArray);
LDDLL_PREFIX LONG WINAPI CopyFrameActive(LONG SourceFrame, LONG DestFrame, LPLONG SUPPLY_ActiveArray);
LDDLL_PREFIX LONG WINAPI CopyBlock(LONG FromFrame, LONG ToFrame, LONG DestFrame);
LDDLL_PREFIX LONG WINAPI ReverseBlock(LONG FromFrame, LONG ToFrame);
LDDLL_PREFIX LONG WINAPI DeleteFrames(LONG FromFr, LONG ToFr);
LDDLL_PREFIX LONG WINAPI MergeFrames(LONG source1fr, LONG source2fr, LONG destfr);
LDDLL_PREFIX LONG WINAPI FrameToUndoActive(LPLONG SUPPLY_ActiveArray); //If no active array is used, supply a NULL pointer.
LDDLL_PREFIX LONG WINAPI UndoToFrameActive(LPLONG RETURN_ActiveArray); //If no active array is used, supply a NULL pointer.
//--------------------------------------------------------------------------------------------
// Vector Frame functions
//--------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI ConvertToVectorFrame(LONG OptimizePath, LONG PreserveBlanking,
LONG StartingX, LONG StartingY, LONG StartingZ);
LDDLL_PREFIX LONG WINAPI ConvertToPointFrame(LONG VisibleBeginEmph, LONG VisibleMiddleEmph,
LONG VisibleEndEmph, LONG VisibleDensity,
LONG BlankedBeginEmph, LONG BlankedEndEmph,
LONG BlankedDensity);
//-------------------------------------------------------------------------------------------
// Point Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI ReadNumPoints(LPLONG RETURN_NumPoints);
LDDLL_PREFIX LONG WINAPI ReadPoint(LONG PointNumber, PTSTRUCT *RETURN_PtStruct);
LDDLL_PREFIX LONG WINAPI WritePoint(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct);
LDDLL_PREFIX LONG WINAPI SetInsertOnWrite(LONG TrueOrFalse); //For WritePoint function
LDDLL_PREFIX LONG WINAPI DeletePoints(LONG FromPt, LONG ToPt);
LDDLL_PREFIX LONG WINAPI InsertPoints(LONG FromPt, LONG ToPt);
LDDLL_PREFIX LONG WINAPI InvertPointsActive(LONG FromPt, LONG ToPt, LONG XOffs, LONG YOffs,
LONG ZOffs, LONG Mask, LPLONG SUPPLY_ActiveArray);
LDDLL_PREFIX LONG WINAPI MovePointsActive(LONG FromPt, LONG ToPt, LONG XOffs, LONG YOffs,
LONG ZOffs, LONG Mask, LPLONG SUPPLY_ActiveArray);
LDDLL_PREFIX LONG WINAPI ResizePointsActive(LONG FromPt, LONG ToPt,
float XResizepct, float YResizepct, float ZResizepct,
LONG XResizectr, LONG YResizectr, LONG ZResizectr,
LONG Mask, LPLONG SUPPLY_ActiveArray);
LDDLL_PREFIX LONG WINAPI RotatePointsActive(LONG FromPt, LONG ToPt,
float XRotatepct, float YRotatepct, float ZRotatepct,
LONG XRotatectr, LONG YRotatectr, LONG ZRotatectr,
LONG Mask, LPLONG SUPPLY_ActiveArray);
LDDLL_PREFIX LONG WINAPI Set_XYZ_TO_3D_Track(LONG Track);
LDDLL_PREFIX LONG WINAPI XYZ_TO_3D(LONG XCoord, LONG YCoord, LONG ZCoord, LPLONG RETURN_X3D, LPLONG RETURN_Y3D, LPLONG RETURN_VisibleFlag);
//-------------------------------------------------------------------------------------------
// Palette and color Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI LoadPalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI LoadPaletteDots(LPSTR ColorFilename, LONG *RETURN_PaletteDotColor1, LONG *RETURN_PaletteDotColor2, LONG *RETURN_PaletteDotColor3, LONG *RETURN_PaletteDotColor4, LONG *RETURN_PaletteDotColor5, LONG *RETURN_PaletteDotColor6, LONG *RETURN_PaletteDotColor7, LONG *RETURN_PaletteDotColor8, char *RETURN_PaletteDotName1, char *RETURN_PaletteDotName2, char *RETURN_PaletteDotName3, char *RETURN_PaletteDotName4, char *RETURN_PaletteDotName5, char *RETURN_PaletteDotName6, char *RETURN_PaletteDotName7, char *RETURN_PaletteDotName8, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SavePalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SavePaletteDots(LPSTR ColorFilename, LONG *SUPPLY_PaletteDotColor1, LONG *SUPPLY_PaletteDotColor2, LONG *SUPPLY_PaletteDotColor3, LONG *SUPPLY_PaletteDotColor4, LONG *SUPPLY_PaletteDotColor5, LONG *SUPPLY_PaletteDotColor6, LONG *SUPPLY_PaletteDotColor7, LONG *SUPPLY_PaletteDotColor8, char *SUPPLY_PaletteDotName1, char *SUPPLY_PaletteDotName2, char *SUPPLY_PaletteDotName3, char *SUPPLY_PaletteDotName4, char *SUPPLY_PaletteDotName5, char *SUPPLY_PaletteDotName6, char *SUPPLY_PaletteDotName7, char *SUPPLY_PaletteDotName8, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI TrainColorSystem(void);
LDDLL_PREFIX LONG WINAPI UseDefaultColors(void);
LDDLL_PREFIX LONG WINAPI EliminateUnusedColors(LONG LastColorNumber);
LDDLL_PREFIX LONG WINAPI UpdateAlternatePalettes(void);
LDDLL_PREFIX LONG WINAPI ReadColorReg(COLORREGSTRUCT *RETURN_ColorStruct);
LDDLL_PREFIX LONG WINAPI ReadColorRegEx(LONG PaletteSelect, COLORREGSTRUCT *RETURN_ColorStruct);
LDDLL_PREFIX LONG WINAPI ReadNumColors(LPLONG RETURN_NumColors);
LDDLL_PREFIX LONG WINAPI WriteColorReg(COLORREGSTRUCT *SUPPLY_ColorStruct);
LDDLL_PREFIX LONG WINAPI WriteColorRegEx(LONG PaletteSelect, COLORREGSTRUCT *SUPPLY_ColorStruct);
LDDLL_PREFIX LONG WINAPI ReadActuatorColorMode(LPLONG RETURN_Mode);
LDDLL_PREFIX LONG WINAPI WriteActuatorColorMode(LONG Mode);
LDDLL_PREFIX LONG WINAPI RGB4toRGB1(LPLONG SUPPLY_Red, LPLONG SUPPLY_Green, LPLONG SUPPLY_Blue,
LPLONG SUPPLY_MSB, LPLONG RETURN_RGBMValue);
LDDLL_PREFIX LONG WINAPI RGB1toRGB4(LPLONG SUPPLY_RGBMValue, LPLONG RETURN_Red, LPLONG RETURN_Green,
LPLONG RETURN_Blue, LPLONG RETURN_MSB);
LDDLL_PREFIX LONG WINAPI RGBtoHSV(LPLONG SUPPLY_RGB, LPLONG RETURN_HSV);
LDDLL_PREFIX LONG WINAPI HSVtoRGB(LPLONG SUPPLY_HSV, LPLONG RETURN_RGB);
//-------------------------------------------------------------------------------------------
// Scale setting and getting functions. Sets coordinate scale for Frame/Point reading/writing
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI SetWorkingScale(LONG LogicalLeft, LONG LogicalRight,
LONG LogicalBottom, LONG LogicalTop,
LONG LogicalRear, LONG LogicalFront);
LDDLL_PREFIX LONG WINAPI SetWorkingScaleX(LONG LogicalLeft, LONG LogicalRight,
LONG LogicalOriginX, LONG DeviceLeft,
LONG DeviceRight, LONG DeviceOriginX);
LDDLL_PREFIX LONG WINAPI SetWorkingScaleY(LONG LogicalBottom, LONG LogicalTop,
LONG LogicalOriginY, LONG DeviceBottom,
LONG DeviceTop, LONG DeviceOriginY);
LDDLL_PREFIX LONG WINAPI SetWorkingScaleZ(LONG LogicalRear, LONG LogicalFront,
LONG LogicalOriginZ, LONG DeviceRear,
LONG DeviceFront, LONG DeviceOriginZ);
LDDLL_PREFIX LONG WINAPI SetWorkingScaleF(LONG LogicalMaxFocus, LONG LogicalOriginF,
LONG DeviceMaxFocus, LONG DeviceOriginF);
LDDLL_PREFIX LONG WINAPI GetWorkingScaleX(LPLONG LogicalLeft, LPLONG LogicalRight,
LPLONG LogicalOriginX, LPLONG DeviceLeft,
LPLONG DeviceRight, LPLONG DeviceOriginX);
LDDLL_PREFIX LONG WINAPI GetWorkingScaleY(LPLONG LogicalBottom, LPLONG LogicalTop,
LPLONG LogicalOriginY, LPLONG DeviceBottom,
LPLONG DeviceTop, LPLONG DeviceOriginY);
LDDLL_PREFIX LONG WINAPI GetWorkingScaleZ(LPLONG LogicalRear, LPLONG LogicalFront,
LPLONG LogicalOriginZ, LPLONG DeviceRear,
LPLONG DeviceFront, LPLONG DeviceOriginZ);
LDDLL_PREFIX LONG WINAPI GetWorkingScaleF(LPLONG LogicalMaxFocus, LPLONG LogicalOriginF,
LPLONG DeviceMaxFocus, LPLONG DeviceOriginF);
//-------------------------------------------------------------------------------------------
// Screen Drawing Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI SetLaserWindow(LONG LeftEdge, LONG RightEdge, LONG BottomEdge, LONG TopEdge, LONG MagLevel);
LDDLL_PREFIX LONG WINAPI DrawGrid(HWND hWnd, LONG gridHvalue, LONG gridVvalue, LONG MClearScreen, LONG MShowZero, LONG MShowGrid);
LDDLL_PREFIX LONG WINAPI RedrawFrame(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
LONG MShowFocus);
LDDLL_PREFIX LONG WINAPI RedrawFrameActive(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
LONG MShowFocus, LPLONG ActiveArray);
LDDLL_PREFIX LONG WINAPI RedrawFrameActiveEx(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
LONG MShowFocus, LONG MShowBlankedLines, LONG MShowBlankedPoints, LPLONG ActiveArray);
LDDLL_PREFIX LONG WINAPI RedrawFrameActiveDC(HWND hWnd, HDC hDC, LONG frompt, LONG topt, LONG ViewMode,
LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
LONG MShowFocus, LPLONG ActiveArray);
LDDLL_PREFIX LONG WINAPI RedrawFrameActiveDCEx(HWND hWnd, HDC hDC, LONG frompt, LONG topt, LONG ViewMode,
LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
LONG MShowFocus, LONG MShowBlankedLines, LONG MShowBlankedPoints, LPLONG ActiveArray);
LDDLL_PREFIX LONG WINAPI RedrawFrameFast(HWND hWnd, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
LDDLL_PREFIX LONG WINAPI RedrawFrameFastDC(HWND hWnd, HDC hDC, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
LDDLL_PREFIX LONG WINAPI RedrawFrameFastDCRECT(HWND hWnd, HDC hDC, RECT *rect, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
//-------------------------------------------------------------------------------------------
// Text functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI SetLineLimits(LONG NumBlanked, LONG NumEmphasis, LONG NumPoints, LONG Density);
LDDLL_PREFIX LONG WINAPI LoadFont(LPSTR FontFilename, LPLONG RETURN_LDStatus);
LDDLL_PREFIX LONG WINAPI SetLaserChar(LONG ViewMode, LONG TextBlanked, LONG TextEmphasis, LONG Density, LONG Width, LONG Height, LONG MaxAngle, LONG AngleDetect, long RGBColor);
LDDLL_PREFIX LONG WINAPI LaserChar(LONG Ascii, LONG XStart, LONG YStart, LONG BeginPoint, LPLONG RETURN_charXEnd, LPLONG RETURN_charYEnd, LPLONG RETURN_charEndPt);
LDDLL_PREFIX LONG WINAPI GetLaserCharExtent(LONG Ascii, LPLONG RETURN_charXExtent, LPLONG RETURN_charYExtent);
//-------------------------------------------------------------------------------------------
// QuadMod32 Parallel Port Functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI ParOn(LONG BankNum, LONG LineNum);
LDDLL_PREFIX LONG WINAPI ParOff(LONG BankNum, LONG LineNum);
LDDLL_PREFIX LONG WINAPI ParIn(LONG BankNum, LONG LineNum, LPLONG RETURN_Value);
LDDLL_PREFIX LONG WINAPI DisplayPortLong(long I_OMask, long OutputValue, LPLONG RETURN_Value);
//-------------------------------------------------------------------------------------------
// Abstract Generator functions
//-------------------------------------------------------------------------------------------
LDDLL_PREFIX LONG WINAPI InitAbstractOsc1(float XPhase, float YPhase, float ZPhase);
LDDLL_PREFIX LONG WINAPI InitAbstractOsc2(float XPhase, float YPhase, float ZPhase);
LDDLL_PREFIX LONG WINAPI InitAbstractOsc3(float XPhase, float YPhase, float ZPhase);
LDDLL_PREFIX LONG WINAPI InitAbstractMod1(float ModPhase);
LDDLL_PREFIX LONG WINAPI InitAbstractMod2(float ModPhase);
LDDLL_PREFIX LONG WINAPI InitAbstractColor(LONG SequenceStart);
LDDLL_PREFIX LONG WINAPI InitAbstractColorNew(float ColorPhase);
LDDLL_PREFIX LONG WINAPI SetAbstractOsc1(float XFreq, float YFreq, float ZFreq, float XSize,
float YSize, float ZSize, LONG Wave);
//Normalized Size Variables
LDDLL_PREFIX LONG WINAPI SetAbstractOsc2(float XFreq, float YFreq, float ZFreq, float XSize,
float YSize, float ZSize, LONG Wave);
//Normalized Size Variables
LDDLL_PREFIX LONG WINAPI SetAbstractOsc3(float XFreq, float YFreq, float ZFreq, float XSize,
float YSize, float ZSize, LONG Wave);
//Normalized Size Variables
LDDLL_PREFIX LONG WINAPI SetAbstractMod1(float ModFreq, float ModAmplitude, LONG ModWave);
//Normalized Amplitude Variable
LDDLL_PREFIX LONG WINAPI SetAbstractMod2(float ModFreq, float ModAmplitude, LONG ModWave);
//Normalized Amplitude Variable
LDDLL_PREFIX LONG WINAPI SetAbstractColor(LONG ColorFreq, LONG ColorWave);
LDDLL_PREFIX LONG WINAPI SetAbstractColorNew(float ColorFreq, LONG ColorWave);
LDDLL_PREFIX LONG WINAPI SwapWaves(void);
LDDLL_PREFIX LONG WINAPI GenerateAbstract(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
LDDLL_PREFIX LONG WINAPI GenerateAbstractNew(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
LDDLL_PREFIX LONG WINAPI GetAbstractPhase(LONG SUPPLY_OscID, float *RETURN_XPhase, float *RETURN_YPhase, float *RETURN_ZPhase);
LDDLL_PREFIX LONG WINAPI GetAbstractFreqSizeWave(LONG SUPPLY_OscID, float *RETURN_XFreq,
float *RETURN_YFreq, float *RETURN_ZFreq,
float *RETURN_XSize, float *RETURN_YSize, float *RETURN_ZSize, int *RETURN_Wave);
LDDLL_PREFIX LONG WINAPI AbstractToFrame(void);
LDDLL_PREFIX LONG WINAPI FrameToAbstract(void);
@@ -0,0 +1,149 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
extern "C" {
#include "ld32.h"
};
int active_state;
int g_laser_nomessage,g_laser_zones;
int init=0;
int ld32_framebase=1;
static void onActivate()
{
if (active_state) return;
active_state=1;
ResetLD();
SetWorkingTracks(-1);
SetWorkingScanners(-1);
DisplayFlags(0);
}
static void onDeactivate()
{
if (!active_state) return;
active_state=0;
ResetLD();
SetWorkingTracks(-1);
SetWorkingScanners(-1);
DisplayFlags(0);
DisplayFrame(0);
DisplayUpdate();
}
void laser_connect(void)
{
LONG v;
InitialQMCheck(&v);
if (v != LDERR_OK)
{
if (!g_laser_nomessage) MessageBox(NULL,"No QM2000 found.","AVS/Laser Error",MB_OK);
return;
}
{
LONG mf,mp,mb,uf,ver;
BeginSessionEx(&ver,&mf, &mp, &mb, &uf, &v);
if (v != LDERR_OK)
{
return;
}
GetLDDLLModuleUsage(&v);
if (v != 1)
{
if (!g_laser_nomessage) MessageBox(NULL,"QM2000 is being shared with other software.","AVS/Laser Warning",MB_OK);
}
else
{
onActivate();
}
ld32_framebase=mf;
}
init=1;
}
extern "C" void LaserQuit();
void laser_disconnect(void)
{
if (!init) return;
init=0;
onDeactivate();
LaserQuit();
}
void laser_sendframe(void *data, int datalen)
{
struct t
{
FRAMESTRUCTEX frame;
PTSTRUCT points[4096];
} *framedata=(struct t *)data;
if (!init) return;
extern int g_laser_nomessage;
if (g_laser_nomessage&4)
{
onDeactivate();
return;
}
if (g_laser_nomessage&2)
{
DWORD dw;
GetWindowThreadProcessId(GetForegroundWindow(),&dw);
if (dw != GetCurrentProcessId())
{
onDeactivate();
return;
}
}
onActivate();
SetWorkingFrame(ld32_framebase);
WriteFrameEx(&framedata->frame,framedata->points);
SetWorkingTracks(1);
DisplayFlags(0);
DisplayFrame(ld32_framebase);
DisplayProjectionZones(g_laser_zones);
LONG bif=0, cop;
if (!(g_laser_nomessage&8)) DisplayBufferStatus(&bif,&cop);
if (!bif)
DisplayUpdate();
}
#endif
@@ -0,0 +1,218 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <math.h>
#include "../r_defs.h"
extern "C" {
#include "ld32.h"
};
static int fix(int a)
{
return ((a&0xff0000)>>16)|(a&0xff00)|((a&0xff)<<16);
}
static int dist(int x1, int y1, int x2, int y2)
{
x1-=x2;
y1-=y2;
return x1*x1+y1*y1;
}
static double actdist(double x1, double y1, double x2, double y2)
{
x1-=x2;
y1-=y2;
return sqrt(x1*x1+y1*y1);
}
static __inline int getval(int x1, int y1, int x2, int y2, int xv)
{
if (x1==x2) return y1;
return y1+MulDiv(xv-x1,y2-y1,x2-x1);
}
static void doclip(int &x1, int &y1, int x2, int y2)
{
if (x1 > 8000 && x2 <= 8000)
{
y1=getval(x1,y1,x2,y2,8000);
x1=8000;
}
if (x1 < -8000 && x2 >= -8000)
{
y1=getval(x1,y1,x2,y2,-8000);
x1=-8000;
}
}
void LineDrawList(C_LineListBase *list, int *fb, int w, int h)
{
LineType *ll;
static struct
{
FRAMESTRUCTEX frame;
PTSTRUCT points[32768];
} d;
memset(&d.frame,0,sizeof(d.frame));
int cp=0;
int lastendx=-10000,lastendy=-10000;
int w2=w/2;
int h2=h/2;
int numl=list->GetUsedLines();
ll=list->GetLineList();
while (numl-->0 && cp < sizeof(d.points)/sizeof(PTSTRUCT)-2)
{
int x1,y1,x2,y2;
// draw to screen
{
x1=(int) (ll->x1 * w2) + w2;
x2=(int) (ll->x2 * w2) + w2;
y1=(int) (ll->y1 * h2) + h2;
y2=(int) (ll->y2 * h2) + h2;
if (ll->mode==0)
{
line(fb,x1,y1,x2,y2,w,h,ll->color);
}
else
{
if (x1 >= 0 && x1 < w && y1 >= 0 && y1 < h)
{
int o=x1+y1*w;
fb[o]=BLEND(fb[o],ll->color);
}
}
}
x1=(int) (ll->x1*8000.0);
x2=(int) (ll->x2*8000.0);
y1=(int) (ll->y1*-8000.0);
y2=(int) (ll->y2*-8000.0);
if (ll->mode==0)
{
doclip(x1,y1,x2,y2);
doclip(x2,y2,x1,y1);
doclip(y1,x1,y2,x2);
doclip(y2,x2,y1,x1);
if (x1 >= -8000 && x1 <= 8000 && y1 >= -8000 && y1 <= 8000 &&
x2 >= -8000 && x2 <= 8000 && y2 >= -8000 && y2 <= 8000)
{
// x1, y1 is the new, far point
if (cp && dist(x1,y1,lastendx,lastendy) < dist(x2,y2,lastendx,lastendy))
{
int t;
t=x1; x1=x2; x2=t;
t=y1; y1=y2; y2=t;
}
// if new start point is too far away, blank to that point
if (dist(x2,y2,lastendx,lastendy) > 400*400 || !cp)
{
memset(&d.points[cp],0,sizeof(d.points[0]));
if (cp)
{
d.points[cp-1].Status=4096;
}
d.points[cp].Status=0;
d.points[cp].XCoord=x2;
d.points[cp].YCoord=y2;
cp++;
}
else if (cp>1 && d.points[cp-1].RGBValue)
{
double a1=atan2(d.points[cp-2].XCoord-x2,d.points[cp-2].YCoord-y2);
double a2=atan2(x2-x1,y2-y1);
if (fabs(a1-a2) >= 1.0*3.14159/180.0)
{
d.points[cp-1].Status=4096;
}
}
lastendx=x1;
lastendy=y1;
memset(&d.points[cp],0,sizeof(d.points[0]));
d.points[cp].RGBValue=fix(ll->color);
d.points[cp].Status=0;
d.points[cp].XCoord=x1;
d.points[cp].YCoord=y1;
cp++;
}
}
else
{
if (x1 > -8000 && x1 < 8000 && y1 > -8000 && y1 < 8000)
{
if (dist(x1,y1,lastendx,lastendy) > 30*30)
{
memset(&d.points[cp],0,sizeof(d.points[0]));
d.points[cp].Status=0;
d.points[cp].XCoord=x1;
d.points[cp].YCoord=y1;
cp++;
}
memset(&d.points[cp],0,2*sizeof(d.points[0]));
d.points[cp].RGBValue=fix(ll->color);
d.points[cp].Status=4096;
d.points[cp].XCoord=x1;
d.points[cp].YCoord=y1;
cp++;
d.points[cp].Status=4096;
d.points[cp].XCoord=x1;
d.points[cp].YCoord=y1;
cp++;
lastendx=x1;
lastendy=y1;
}
}
ll++;
}
if (cp)
{
d.points[cp-1].Status=4096;
}
memset(&d.frame,0,sizeof(d.frame));
d.frame.VectorFlag=1;
d.frame.NumPoints=max(cp,1);
d.frame.ScanRate=100;
memcpy(d.frame.FrameNote,"AVS/Laser Frame ",24);
laser_sendframe(&d,sizeof(d.frame)+sizeof(PTSTRUCT)*max(cp,16));
}
#endif
@@ -0,0 +1,55 @@
/*
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.
*/
#ifdef LASER
#include "linelist.h"
void LineDrawList(C_LineListBase *list, int *fb, int w, int h);
void laser_connect(void);
void laser_disconnect(void);
void laser_sendframe(void *data, int datalen);
static void __inline laser_drawpoint(float x, float y, int current_color)
{
LineType line;
line.color=current_color;
line.mode=1;
line.x2=0;
line.x1=x;
line.y2=0;
line.y1=y;
g_laser_linelist->AddLine(&line);
}
#else
#ifndef laser_drawpoint
#define laser_drawpoint(x,y,c)
#endif
#endif
@@ -0,0 +1,187 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include "ld32.h"
static HINSTANCE hDll;
LONG (WINAPI *_LoadPalette)(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
LONG (WINAPI *_WritePoint)(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct);
LONG (WINAPI *_InitialQMCheck)(LPLONG RETURN_LDStatus);
LONG (WINAPI *_DisplayUpdate)(void);
LONG (WINAPI *_DisplayBufferStatus)(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints);
LONG (WINAPI *_DisplayFrame)(LONG Frame);
LONG (WINAPI *_WriteFrameEx)(FRAMESTRUCTEX *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray);
LONG (WINAPI *_SetWorkingScanners)(LONG Scanner);
LONG (WINAPI *_SetWorkingTracks)(LONG Track);
LONG (WINAPI *_SetWorkingFrame)(LONG FrameNumber);
LONG (WINAPI *_BeginSessionEx)(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
LONG (WINAPI *_DisplayFlags)(LONG Flags);
LONG (WINAPI *_EndSession)(void);
LONG (WINAPI *_GetLDDLLModuleUsage)(LPLONG ModuleUsage);
LONG (WINAPI *_ResetLD)(void); //Updates all track variables
LONG (WINAPI *_ReadProjectionZone)(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ);
LONG (WINAPI *_OpenLDCommWindow)(void);
LONG (WINAPI *_DisplayProjectionZones)(long ProjectionZoneCode);
LONG WINAPI InitialQMCheck(LPLONG RETURN_LDStatus)
{
hDll=LoadLibrary("ld2000.dll");
if (!hDll)
{
// printf("LD2000: error loading DLL\n");
*RETURN_LDStatus=1;
return 1;
}
#define RETR(x) *((void**)&_##x)=(void*)GetProcAddress(hDll,#x); if (!_##x) { FreeLibrary(hDll); hDll=0; *RETURN_LDStatus=1; return 1; }
// \
// if (!_##x) printf("LD2000: error loading DLL: " #x "\n");
RETR(ReadProjectionZone);
RETR(InitialQMCheck);
RETR(DisplayUpdate);
RETR(DisplayBufferStatus);
RETR(DisplayFrame);
RETR(WriteFrameEx);
RETR(WritePoint);
RETR(SetWorkingScanners);
RETR(LoadPalette);
RETR(SetWorkingTracks);
RETR(SetWorkingFrame);
RETR(EndSession);
RETR(BeginSessionEx);
RETR(DisplayFlags);
RETR(ResetLD);
RETR(OpenLDCommWindow);
RETR(GetLDDLLModuleUsage);
RETR(DisplayProjectionZones);
return _InitialQMCheck(RETURN_LDStatus);
}
LONG WINAPI DisplayProjectionZones(long ProjectionZoneCode)
{
return _DisplayProjectionZones(ProjectionZoneCode);
}
LONG WINAPI ReadProjectionZone(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ)
{
if (!hDll||!_ReadProjectionZone) return 1;
return _ReadProjectionZone(ZoneNumber,RETURN_PZ);
}
LONG WINAPI DisplayBufferStatus(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints)
{
return _DisplayBufferStatus(RETURN_BufferIsFree,RETURN_CurrentOutputPoints);
}
LONG WINAPI DisplayUpdate(void)
{
return _DisplayUpdate();
}
LONG WINAPI DisplayFrame(LONG Frame)
{
return _DisplayFrame(Frame);
}
LONG WINAPI WriteFrameEx(FRAMESTRUCTEX *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray)
{
return _WriteFrameEx(SUPPLY_FrameStruct,SUPPLY_PointArray);
}
LONG WINAPI SetWorkingScanners(LONG Scanner)
{
return _SetWorkingScanners(Scanner);
}
LONG WINAPI SetWorkingTracks(LONG Track)
{
return _SetWorkingTracks(Track);
}
LONG WINAPI SetWorkingFrame(LONG FrameNumber)
{
return _SetWorkingFrame(FrameNumber);
}
LONG WINAPI OpenLDCommWindow(void)
{
return _OpenLDCommWindow();
}
LONG WINAPI EndSession(void)
{
return _EndSession();
}
LONG WINAPI LoadPalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus)
{
return _LoadPalette(ColorFilename,RETURN_LDStatus);
}
LONG WINAPI WritePoint(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct)
{
return _WritePoint(PointNumber,SUPPLY_PtStruct);
}
LONG WINAPI GetLDDLLModuleUsage(LPLONG ModuleUsage)
{
return _GetLDDLLModuleUsage(ModuleUsage);
}
LONG WINAPI ResetLD()
{
return _ResetLD();
}
LONG WINAPI BeginSessionEx(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus)
{
return _BeginSessionEx(
RETURN_Version, RETURN_MaxFrames,
RETURN_MaxPoints, RETURN_MaxBuffer,
RETURN_UndoFrames,RETURN_LDStatus);
}
LONG WINAPI DisplayFlags(LONG Flags)
{
return _DisplayFlags(Flags);
}
void LaserQuit()
{
if (hDll) FreeLibrary(hDll);
hDll=0;
_InitialQMCheck=0;
}
#endif
@@ -0,0 +1,107 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include "linelist.h"
class C_LineList : public C_LineListBase
{
private:
int max;
int used;
LineType *linelist;
public:
C_LineList() { max=16384; linelist=(LineType *)malloc(16384*sizeof(LineType)); used=0; };
virtual ~C_LineList() { free(linelist); }
virtual int GetMaxLines(void) { return max; };
virtual int GetUsedLines(void) { return used; };
virtual void SetUsedLines(int usedlines) { used=usedlines; }
virtual void SetLines(LineType *list, int start, int length) { memcpy(linelist+start,list,length*sizeof(LineType)); }
virtual void SetMaxLines(int m);
virtual void ClearLineList(void);
virtual LineType *GetLineList(void);
virtual void AddLine(LineType *line);
void swapcontents(C_LineList *other)
{
{
int tmp;
tmp=max;
max=other->max;
other->max=tmp;
tmp=used;
used=other->used;
other->used=tmp;
}
LineType *tmp;
tmp=linelist;
linelist=other->linelist;
other->linelist=tmp;
}
};
C_LineListBase *createLineList(void)
{
return (C_LineListBase *)new C_LineList();
}
void LineListSwap(C_LineListBase *item1, C_LineListBase *item2)
{
C_LineList *i1=(C_LineList*)item1;
C_LineList *i2=(C_LineList*)item2;
i1->swapcontents(i2);
}
void C_LineList::SetMaxLines(int m)
{
if (m > 16384) m = 16384;
max=m;
if (used > max) ClearLineList();
}
void C_LineList::ClearLineList(void)
{
used=0;
}
LineType *C_LineList::GetLineList(void)
{
return linelist;
}
void C_LineList::AddLine(LineType *line)
{
if (used >= max) return;
memcpy(linelist+used,line,sizeof(LineType));
used++;
}
#endif
@@ -0,0 +1,57 @@
/*
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.
*/
#ifdef LASER
typedef struct
{
float x1, y1;
float x2, y2;
int color;
int mode;
} LineType;
class C_LineListBase
{
public:
C_LineListBase(){ };
virtual ~C_LineListBase() { };
virtual int GetMaxLines(void)=0;
virtual int GetUsedLines(void)=0;
virtual void SetMaxLines(int m)=0;
virtual void SetUsedLines(int usedlines)=0;
virtual void SetLines(LineType *list, int start, int length)=0;
virtual void ClearLineList(void)=0;
virtual LineType *GetLineList(void)=0;
virtual void AddLine(LineType *line)=0;
};
C_LineListBase *createLineList(void);
extern C_LineListBase *g_laser_linelist;
#endif
@@ -0,0 +1,165 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <commctrl.h>
#include "../r_defs.h"
#include "../resource.h"
#include <math.h>
#define C_THISCLASS CLASER_BeatHoldClass
#define MOD_NAME "Misc / Beat Hold"
class C_THISCLASS : public C_RBASE {
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); // returns 1 if fbout has dest
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 decayMS, beatSkip;
DWORD isBeatDecay;
int beatCount;
LineType m_linelist[1024];
int linelist_used;
};
#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; pos+=4
#define GET_INT(a) if (len-pos>=4) { (a)=(data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24)); pos += 4; }
void C_THISCLASS::load_config(unsigned char *data, int len)
{
int pos=0;
int x=0;
GET_INT(decayMS);
GET_INT(beatSkip);
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(decayMS);
PUT_INT(beatSkip);
return pos;
}
C_THISCLASS::C_THISCLASS()
{
isBeatDecay=0;
decayMS=500;
beatCount=0;
beatSkip=4;
linelist_used=0;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
{
if (isBeat&0x80000000) return 0;
if (isBeatDecay)
{
if (GetTickCount() > isBeatDecay)
{
isBeatDecay=0;
}
else
{
g_laser_linelist->SetLines(m_linelist,0,linelist_used);
g_laser_linelist->SetUsedLines(linelist_used);
}
}
else if (isBeat && ++beatCount > beatSkip)
{
beatCount=0;
isBeatDecay=GetTickCount()+decayMS;
linelist_used=g_laser_linelist->GetUsedLines();
memcpy(m_linelist,g_laser_linelist->GetLineList(),linelist_used*sizeof(LineType));
}
return 0;
}
C_RBASE *RLASER_BeatHold(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,20);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->decayMS/100);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,16);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->beatSkip);
return 1;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->decayMS=t*100;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
{
g_this->beatSkip=t;
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_BEATHOLD,hwndParent,g_DlgProc);
}
#endif
@@ -0,0 +1,183 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <commctrl.h>
#include "../r_defs.h"
#include "../resource.h"
#include <math.h>
#define C_THISCLASS CLASER_BrenClass
#define MOD_NAME "Render / Brennan\'s Effect"
typedef struct {
float x, y;
} PT;
typedef struct {
PT pt[4];
} segment;
#define BOUND (0.6f)
#define NSEG 48
#define VISSEG 6
class C_THISCLASS : public C_RBASE {
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); // returns 1 if fbout has dest
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);
segment seg[NSEG];
PT d[4];
float phase;
int step;
};
#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;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0,x=0;
return pos;
}
float frandom() {
return (float)rand() / (float)RAND_MAX;
}
C_THISCLASS::C_THISCLASS()
{
int i, j;
for (j = 0; j < NSEG; j++) {
for (i = 0; i < 4; i++) {
// seg[j].pt[i].x = frandom() * 2.0 - 1.0;
// seg[j].pt[i].y = frandom() * 2.0 - 1.0;
seg[j].pt[i].x = 0.f;
seg[j].pt[i].y = 0.f;
}
}
for (i = 0; i < 4; i++) {
d[i].x = frandom() * 0.015 + 0.005;
d[i].y = frandom() * 0.015 + 0.005;
}
phase = 0.0;
step = 0;
}
C_THISCLASS::~C_THISCLASS()
{
}
#define PI 3.14159
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
{
if (isBeat&0x80000000) return 0;
LineType l;
int i, j;
float s;
s = sin(phase * 2 * PI)*0.10+0.9;
//s = 1.0;
//s = 0.8 + isBeat * 0.2;
for (i = 0; i < 4; i++) {
seg[0].pt[i].x += d[i].x * s;
seg[0].pt[i].y += d[i].y * s;
if (seg[0].pt[i].x < -BOUND || seg[0].pt[i].x > BOUND) d[i].x = -d[i].x;
if (seg[0].pt[i].y < -BOUND || seg[0].pt[i].y > BOUND) d[i].y = -d[i].y;
}
for (j = 0; j < NSEG; j++) {
static PT p;
if ((step++ % (NSEG/VISSEG)) != 0) continue;
for (i = 0; i < 4; i++) {
l.mode=0;
l.color=RGB(0, 0, 255);
l.x1= seg[j].pt[i].x * s;
l.y1= seg[j].pt[i].y * s;
l.x2= (p.x)*s;
l.y2= (p.y)*s;
p = seg[j].pt[i];
g_laser_linelist->AddLine(&l);
l.x1 = l.x2;
l.y1 = l.y2;
l.mode=1;
l.color=RGB(0, 255, 0);
g_laser_linelist->AddLine(&l);
}
}
for (i = NSEG-1; i > 0; i--) {
seg[i] = seg[i-1];
}
phase += 0.005f;
return 0;
}
C_RBASE *RLASER_Bren(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)
{
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return 0;//WASABI_API_CREATEDIALOG(IDD_CFG_LINE,hwndParent,g_DlgProc);
}
#endif
@@ -0,0 +1,363 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <commctrl.h>
#include "../r_defs.h"
#include "../resource.h"
#include <math.h>
#define C_THISCLASS CLASER_MovingConeClass
#define MOD_NAME "Render / Moving Cone"
class C_THISCLASS : public C_RBASE {
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); // returns 1 if fbout has dest
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 maxdist[2],size,size2,num_seg;
int s_pos;
int beatcnt;
double c[2];
double v[2];
double p[2];
int mode;
int colors[16],num_colors;
int color_pos;
};
#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;
int x=0;
if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
else num_colors=0;
if (len-pos >= 4) { maxdist[0]=maxdist[1]=GET_INT(); pos+=4; }
if (len-pos >= 4) { size=GET_INT(); pos+=4; }
if (len-pos >= 4) { size2=GET_INT(); pos+=4; }
if (len-pos >= 4) { num_seg=GET_INT(); pos+=4; }
if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
if (len-pos >= 4) { maxdist[1]=GET_INT(); pos+=4; }
s_pos=size;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0,x=0;
PUT_INT(num_colors); pos+=4;
while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
PUT_INT(maxdist[0]); pos+=4;
PUT_INT(size); pos+=4;
PUT_INT(size2); pos+=4;
PUT_INT(num_seg); pos+=4;
PUT_INT(mode); pos+=4;
PUT_INT(maxdist[1]); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
num_seg=8;
size=size2=s_pos=8;
maxdist[0]=maxdist[1]=16;
c[0]=c[1]=0.0f;
v[0]=-0.01551;
v[1]=0.0;
p[0]=-0.6;
p[1]=0.3;
num_colors=1;
memset(colors,0,sizeof(colors));
colors[0]=RGB(255,255,255);
color_pos=0;
beatcnt=0;
mode=0;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
{
if (isBeat&0x80000000) return 0;
LineType l;
int x;
int current_color;
if (!num_colors) return 0;
color_pos++;
if (color_pos >= num_colors * 64) color_pos=0;
{
int p=color_pos/64;
int r=color_pos&63;
int c1,c2;
int r1,r2,r3;
c1=colors[p];
if (p+1 < num_colors)
c2=colors[p+1];
else c2=colors[0];
r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
current_color=r1|(r2<<8)|(r3<<16);
}
float xp,yp;
if (isBeat)
{
c[0]=((rand()%33)-16)/48.0f;
c[1]=((rand()%33)-16)/48.0f;
}
{
if (p[0] >= 0.0000001 || p[0] <= -0.0000001) v[0] -= 0.004*(p[0]-c[0]);
if (p[1] >= 0.0000001 || p[1] <= -0.0000001) v[1] -= 0.004*(p[1]-c[1]);
}
p[0]+=v[0];
p[1]+=v[1];
v[0]*=0.991;
v[1]*=0.991;
xp=(float) (p[0]*(maxdist[0]/32.0));
yp=(float) (p[1]*(maxdist[1]/32.0));
if (isBeat)
s_pos=size2;
int sz=s_pos;
s_pos=(s_pos+size)/2;
{
float dx,dy;
float lx,ly;
lx=(float) (cos(0.0)*s_pos/75.0);
ly=(float) (sin(0.0)*s_pos/75.0);
for (x = 0; x < num_seg; x ++)
{
l.mode=mode;
l.color=current_color;
dx=(float) (cos(0.0+(x+1)*3.14159*2.0/num_seg)*s_pos/75.0);
dy=(float) (sin(0.0+(x+1)*3.14159*2.0/num_seg)*s_pos/75.0);
if (!mode)
{
l.x2=xp+lx;
l.y2=yp+ly;
}
else l.x2=l.y2=0;
l.x1=xp+dx;
l.y1=yp+dy;
lx=dx;
ly=dy;
int x=(int) (l.x1*(w/2)+(w/2));
int y=(int) (l.y1*(h/2)+(h/2));
g_laser_linelist->AddLine(&l);
}
}
return 0;
}
C_RBASE *RLASER_Cone(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
{
int x;
int w=di->rcItem.right-di->rcItem.left;
int l=0,nl;
for (x = 0; x < g_this->num_colors; x ++)
{
int color=g_this->colors[x];
nl = (w*(x+1))/g_this->num_colors;
color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
HPEN hPen,hOldPen;
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={BS_SOLID,color,0};
hPen = (HPEN)CreatePen(PS_SOLID,0,color);
hBrush = CreateBrushIndirect(&lb);
hOldPen=(HPEN)SelectObject(di->hDC,hPen);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
SelectObject(di->hDC,hOldPen);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
DeleteObject(hPen);
l=nl;
}
}
}
return 0;
case WM_INITDIALOG:
SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->num_seg,FALSE);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->maxdist[0]);
SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETRANGEMAX,0,32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETPOS,1,g_this->maxdist[1]);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,128);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->size);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,128);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->size2);
if (g_this->mode) CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
else CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_RADIO1:
case IDC_RADIO2:
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
g_this->mode=1;
else g_this->mode=0;
break;
case IDC_EDIT1:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
if (tr)
{
g_this->num_seg=p;
}
}
break;
case IDC_NUMCOL:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
if (tr)
{
if (p > 16) p = 16;
g_this->num_colors=p;
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
}
break;
case IDC_DEFCOL:
{
int wc=-1,w,h;
POINT p;
RECT r;
GetCursorPos(&p);
GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
p.x -= r.left;
p.y -= r.top;
w=r.right-r.left;
h=r.bottom-r.top;
if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
{
wc = (p.x*g_this->num_colors)/w;
}
if (wc>=0)
{
GR_SelectColor(hwndDlg,g_this->colors+wc);
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
} }
return 0;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->maxdist[0]=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER7))
{
g_this->maxdist[1]=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
{
g_this->s_pos=g_this->size=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
{
g_this->s_pos=g_this->size2=t;
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_CONE,hwndParent,g_DlgProc);
}
#endif
@@ -0,0 +1,338 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <commctrl.h>
#include "../r_defs.h"
#include "../resource.h"
#include <math.h>
#define C_THISCLASS C_MovingLineClass
#define MOD_NAME "Render / Moving Line"
class C_THISCLASS : public C_RBASE {
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); // returns 1 if fbout has dest
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 maxdist,size,size2,maxbeatcnt;
int s_pos;
int beatcnt;
double angle,dangle;
double c[2];
double v[2];
double p[2];
int colors[16],num_colors;
int color_pos;
};
#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;
int x=0;
if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
else num_colors=0;
if (len-pos >= 4) { maxdist=GET_INT(); pos+=4; }
if (len-pos >= 4) { size=GET_INT(); pos+=4; }
if (len-pos >= 4) { size2=GET_INT(); pos+=4; }
if (len-pos >= 4) { maxbeatcnt=GET_INT(); pos+=4; }
s_pos=size;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0,x=0;
PUT_INT(num_colors); pos+=4;
while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
PUT_INT(maxdist); pos+=4;
PUT_INT(size); pos+=4;
PUT_INT(size2); pos+=4;
PUT_INT(maxbeatcnt); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
size=size2=s_pos=8;
maxdist=16;
c[0]=c[1]=0.0f;
v[0]=-0.01551;
v[1]=0.0;
angle=0.0;
dangle=3.14159/180.0*8.0;
p[0]=-0.6;
p[1]=0.3;
num_colors=1;
maxbeatcnt=16;
memset(colors,0,sizeof(colors));
colors[0]=RGB(255,255,255);
color_pos=0;
beatcnt=0;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
{
if (isBeat&0x80000000) return 0;
LineType l;
int current_color;
if (!num_colors) return 0;
color_pos++;
if (color_pos >= num_colors * 64) color_pos=0;
{
int p=color_pos/64;
int r=color_pos&63;
int c1,c2;
int r1,r2,r3;
c1=colors[p];
if (p+1 < num_colors)
c2=colors[p+1];
else c2=colors[0];
r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
current_color=r1|(r2<<8)|(r3<<16);
}
l.mode=0;
l.color=current_color;
double xp,yp;
if (isBeat)
{
if (maxbeatcnt && ++beatcnt >= maxbeatcnt)
{
beatcnt=0;
dangle=-dangle;
}
c[0]=((rand()%33)-16)/48.0f;
c[1]=((rand()%33)-16)/48.0f;
}
{
if (p[0] >= 0.0000001 || p[0] <= -0.0000001) v[0] -= 0.004*(p[0]-c[0]);
if (p[1] >= 0.0000001 || p[1] <= -0.0000001) v[1] -= 0.004*(p[1]-c[1]);
}
p[0]+=v[0];
p[1]+=v[1];
v[0]*=0.991;
v[1]*=0.991;
xp=(p[0]*(maxdist/32.0));
yp=(p[1]*(maxdist/32.0));
if (isBeat)
s_pos=size2;
int sz=s_pos;
s_pos=(s_pos+size)/2;
{
double dx,dy;
dx=cos(angle)*s_pos/75.0;
dy=sin(angle)*s_pos/75.0;
l.x1=(float) (xp-dx);
l.y1=(float) (yp-dy);
l.x2=(float) (xp+dx);
l.y2=(float) (yp+dy);
g_laser_linelist->AddLine(&l);
angle += dangle;
}
return 0;
}
C_RBASE *RLASER_Line(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
{
int x;
int w=di->rcItem.right-di->rcItem.left;
int l=0,nl;
for (x = 0; x < g_this->num_colors; x ++)
{
int color=g_this->colors[x];
nl = (w*(x+1))/g_this->num_colors;
color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
HPEN hPen,hOldPen;
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={BS_SOLID,color,0};
hPen = (HPEN)CreatePen(PS_SOLID,0,color);
hBrush = CreateBrushIndirect(&lb);
hOldPen=(HPEN)SelectObject(di->hDC,hPen);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
SelectObject(di->hDC,hOldPen);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
DeleteObject(hPen);
l=nl;
}
}
}
return 0;
case WM_INITDIALOG:
SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->maxdist);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,128);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->size);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,1);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,128);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->size2);
SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->maxbeatcnt,FALSE);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_EDIT1:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
if (tr)
{
g_this->maxbeatcnt=p;
}
}
break;
case IDC_NUMCOL:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
if (tr)
{
if (p > 16) p = 16;
g_this->num_colors=p;
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
}
break;
case IDC_DEFCOL:
{
int wc=-1,w,h;
POINT p;
RECT r;
GetCursorPos(&p);
GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
p.x -= r.left;
p.y -= r.top;
w=r.right-r.left;
h=r.bottom-r.top;
if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
{
wc = (p.x*g_this->num_colors)/w;
}
if (wc>=0)
{
GR_SelectColor(hwndDlg,g_this->colors+wc);
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
} }
return 0;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->maxdist=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
{
g_this->s_pos=g_this->size=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
{
g_this->s_pos=g_this->size2=t;
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_LINE,hwndParent,g_DlgProc);
}
#endif
@@ -0,0 +1,338 @@
/*
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.
*/
#ifdef LASER
#include <windows.h>
#include <commctrl.h>
#include "../r_defs.h"
#include "../resource.h"
#include "../evallib/eval.h"
#include "../evallib/compiler.h"
#include <math.h>
#define C_THISCLASS CLASER_Transform
#define MOD_NAME "Misc / Transform"
class C_THISCLASS : public C_RBASE {
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); // returns 1 if fbout has dest
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);
void load_string(RString &s,unsigned char *data, int &pos, int len);
void save_string(unsigned char *data, int &pos, RString &text);
void dopoint(float &x, float &y, char visdata[2][2][576], int &color);
varType vars[EVAL_MAX_VARS];
NSEEL_CODEHANDLE codehandle,codehandle_b,codehandle_i,codehandle_f;
double *v_d;
double *v_r;
double *v_x;
double *v_y;
double *v_b;
double *v_red;
double *v_green;
double *v_blue;
int rectangular;
RString effect_exp[4];
int effect_exp_ch;
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;
rectangular=GET_INT(); pos+=4;
if (data[pos] == 1)
{
pos++;
load_string(effect_exp[0],data,pos,len);
load_string(effect_exp[1],data,pos,len);
load_string(effect_exp[2],data,pos,len);
load_string(effect_exp[3],data,pos,len);
}
else
{
char buf[1025];
if (len-pos >= 1024)
{
memcpy(buf,data+pos,1024);
pos+=1024;
buf[1024]=0;
effect_exp[3].assign(buf+768);
buf[768]=0;
effect_exp[2].assign(buf+512);
buf[512]=0;
effect_exp[1].assign(buf+256);
buf[256]=0;
effect_exp[0].assign(buf);
}
}
effect_exp_ch=1;
}
void C_THISCLASS::load_string(RString &s,unsigned char *data, int &pos, int len) // read configuration of max length "len" from data.
{
int size=GET_INT(); pos += 4;
if (size > 0 && len-pos >= size)
{
s.resize(size);
memcpy(s.get(), data+pos, size);
pos+=size;
}
else
{
s.resize(1);
s.get()[0]=0;
}
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(rectangular); pos+=4;
data[pos++]=1;
save_string(data,pos,effect_exp[0]);
save_string(data,pos,effect_exp[1]);
save_string(data,pos,effect_exp[2]);
save_string(data,pos,effect_exp[3]);
return pos;
}
// special version that encodes with a 1 at the start.
void C_THISCLASS::save_string(unsigned char *data, int &pos, RString &text)
{
if (text.get() && text.get()[0])
{
int l=(strlen(text.get())+1);
PUT_INT(l); pos+=4;
memcpy(data+pos, text.get(), strlen(text.get())+1);
pos+=strlen(text.get())+1;
}
else
{
PUT_INT(0);
pos+=4;
}
}
C_THISCLASS::C_THISCLASS()
{
rectangular=0;
codehandle=0;
codehandle_b=0;
codehandle_i=0;
codehandle_f=0;
memset(vars,0,sizeof(vars));
resetVars(vars);
v_d = registerVar("d");
v_r = registerVar("r");
v_x = registerVar("x");
v_y = registerVar("y");
v_b = registerVar("b");
v_red = registerVar("red");
v_green = registerVar("green");
v_blue = registerVar("blue");
resetVars(NULL);
effect_exp[0].assign("d=0.5;");
effect_exp[1].assign("");
effect_exp[2].assign("");
effect_exp[3].assign("");
effect_exp_ch=1;
InitializeCriticalSection(&rcs);
}
C_THISCLASS::~C_THISCLASS()
{
freeCode(codehandle);
freeCode(codehandle_b);
freeCode(codehandle_i);
freeCode(codehandle_f);
codehandle=0;
codehandle_b=0;
codehandle_i=0;
codehandle_f=0;
DeleteCriticalSection(&rcs);
}
void C_THISCLASS::dopoint(float &x, float &y, char visdata[2][2][576], int &color)
{
*v_d=sqrt(x*x+y*y);
*v_r=atan2(y,x) + 3.14159*0.5;
*v_x=x;
*v_y=y;
*v_blue=(color&0xff)/255.0;
*v_green=((color>>8)&0xff)/255.0;
*v_red=((color>>16)&0xff)/255.0;
executeCode(codehandle,visdata);
if (rectangular)
{
x=*v_x;
y=*v_y;
}
else
{
*v_r -= 3.14159*0.5;
if (*v_r < 0.0) *v_r += 3.14159*2.0;
if (*v_r >= 3.14159*2.0) *v_r -= 3.14159*2.0;
x=cos(*v_r)* *v_d;
y=sin(*v_r)* *v_d;
}
int a=(int)(*v_blue * 255.0);
if (a>255) a=255;
if (a<0)a=0;
color=a;
a=(int)(*v_green * 255.0);
if (a>255) a=255;
if (a<0)a=0;
color|=a<<8;
a=(int)(*v_red * 255.0);
if (a>255) a=255;
if (a<0)a=0;
color|=a<<16;
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
{
if (isBeat&0x80000000) return 0;
if (effect_exp_ch || !codehandle)
{
EnterCriticalSection(&rcs);
memset(vars,0,sizeof(vars));
resetVars(vars);
if (codehandle) freeCode(codehandle);
if (codehandle_b) freeCode(codehandle_b);
if (codehandle_i) freeCode(codehandle_i);
if (codehandle_f) freeCode(codehandle_f);
codehandle=compileCode(effect_exp[0].get());
codehandle_i=compileCode(effect_exp[1].get());
codehandle_f=compileCode(effect_exp[2].get());
codehandle_b=compileCode(effect_exp[3].get());
effect_exp_ch=0;
resetVars(NULL);
LeaveCriticalSection(&rcs);
executeCode(codehandle_i,visdata);
}
executeCode(codehandle_f,visdata);
if (isBeat)
executeCode(codehandle_b,visdata);
if (codehandle)
{
*v_b=isBeat?1.0:0.0;
int x,num=g_laser_linelist->GetUsedLines();
LineType *l=g_laser_linelist->GetLineList();
for (x = 0; x < num; x ++)
{
dopoint(l->x1,l->y1,visdata,l->color);
if (l->mode == 0) dopoint(l->x2,l->y2,visdata,l->color);
l++;
}
}
return 0;
}
C_RBASE *RLASER_Transform(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;
int *a=NULL;
switch (uMsg)
{
case WM_INITDIALOG:
isstart=1;
SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
isstart=0;
if (g_this->rectangular)
CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
return 1;
case WM_COMMAND:
if ((
LOWORD(wParam) == IDC_EDIT1 ||
LOWORD(wParam) == IDC_EDIT2 ||
LOWORD(wParam) == IDC_EDIT3 ||
LOWORD(wParam) == IDC_EDIT4
)
&& HIWORD(wParam) == EN_CHANGE)
{
if (!isstart)
{
EnterCriticalSection(&g_this->rcs);
g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
g_this->effect_exp_ch=1;
LeaveCriticalSection(&g_this->rcs);
}
}
if (LOWORD(wParam) == IDC_CHECK3)
{
EnterCriticalSection(&g_this->rcs);
g_this->rectangular=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
g_this->effect_exp_ch=1;
LeaveCriticalSection(&g_this->rcs);
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_TRANSFORM,hwndParent,g_DlgProc);
}
#endif
@@ -0,0 +1,261 @@
/*
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.
*/
#include <windows.h>
#include "r_defs.h"
#include <math.h>
#define SWAP(x,y,temp) ( temp ) = ( x ); ( x ) = ( y ); ( y ) = ( temp )
#define ABS(x) (( x ) < 0 ? - ( x ) : ( x ))
void line(int *fb, int x1,int y1,int x2,int y2, int width, int height, int color, int lw)
{
int dy = ABS(y2-y1);
int dx = ABS(x2-x1);
#ifdef LASER
lw=1;
#define BLEND_LINE(fb,color) (*(fb)=BLEND(*(fb),(color)))
#else
if (lw<1) lw=1;
else if (lw>255)lw=255;
#endif
int lw2=lw/2;
if (!dx) // optimize vertical draw
{
x1-=lw2;
if (x1+lw >= 0 && x1 < width)
{
int d=max(min(y1,y2),0);
int ye=min(max(y1,y2),height-1);
if (x1<0)
{
lw+=x1;
x1=0;
}
if (x1+lw >= width) lw=width-x1;
fb += d*width+x1;
width-=lw;
if (lw>0) while (d++ < ye)
{
int x=lw;
while (x--) { BLEND_LINE(fb, color); fb++; }
fb+=width;
}
}
return;
}
if (y1==y2) // optimize horizontal draw.
{
y1-=lw2;
if (y1+lw >= 0 && y1 < height)
{
int d=max(min(x1,x2),0);
int xe=min(max(x1,x2),width-1);
if (y1<0)
{
lw+=y1;
y1=0;
}
if (y1+lw >= height) lw=height-y1;
fb+=y1*width+d;
width-=xe-d;
int y=lw;
while (y--)
{
int lt=d;
while (lt++<xe) { BLEND_LINE(fb,color); fb++; }
fb+=width;
}
}
return;
}
if (dy <= dx) // x major, low slope
{
// first things first for better line drawing, let's see if we can't get the
// width calculated right.
// lw is the width in pixels. if dy = 0, then lw=lw. if dy=dx, then:
/*
__________ C=30d
|\
| \ lw
| \_____ A=90d
? | /
| / pc2
|/ ____ B = 60d
tan(C) = sin(C)/cos(C) = (dy / dx)
cos(C) = lw / ?
sin(C)/(lw / ? ) = (dy / dx)
sin(C) * ? / lw = (dy/dx)
sin(C) * ? = lw * dy/dx;
? = lw * dy/dx / sin(C)
cos(C) = lw / ? === ? = lw / cos(C)
tan(C) = dy / dx;
C = atan2(dy,dx);
? = lw / cos(C)
*/
#if 0// lame
if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
double d=atan2((double)dy,(double)dx);
lw = (int) (lw / cos(d));
if (lw<1)lw=1;
}
#endif
if (x2 < x1)
{
int temp;
SWAP(x1,x2,temp);
SWAP(y1,y2,temp);
}
int yincr = y2>y1?1:-1;
int offsincr= y2>y1?width:-width;
y1-=lw2;
int offs = y1 * width + x1;
int d = dy + dy - dx;
int Eincr = dy + dy;
int NEincr = d - dx;
if (x2 >= 0 && x1 < width)
{
if (x1<0)
{
int v;
v=yincr * -x1;
if (dx) v= (v * dy)/dx;
y1 += v;
offs += v*width - x1;
x1=0;
}
if (x2 > width) x2=width;
while (x1<x2)
{
int yp=y1;
int ype=y1+lw;
int *newfb=fb+offs;
if (yp < 0)
{
newfb-=yp*width;
yp=0;
}
if (ype>height) ype=height;
while (yp++ < ype)
{
BLEND_LINE(newfb,color);
newfb+=width;
}
if (d < 0) d += Eincr;
else
{
d += NEincr;
y1 += yincr;
offs += offsincr;
}
offs++;
x1++;
}
}
}
else
{
#if 0//lame
if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
double d=atan2((double)dx,(double)dy);
lw = (int) (lw / cos(d));
if (lw<1)lw=1;
}
#endif
if (y2 < y1)
{
int temp;
SWAP(x1,x2,temp);
SWAP(y1,y2,temp);
}
int yincr=(x2>x1)?1:-1;
int d = dx + dx - dy;
int Eincr = dx + dx;
int NEincr = d - dy;
x1-=lw2;
int offs = y1 * width + x1;
if (y2 >= 0 && y1 < height)
{
if (y1<0)
{
int v;
v=yincr * -y1;
if (dy) v= (v * dx)/dy;
x1 += v;
offs += v - y1*width;
y1=0;
}
if (y2 > height) y2 = height;
while (y1 < y2)
{
int xp=x1;
int xpe=x1+lw;
int *newfb=fb+offs;
if (xp<0)
{
newfb-=xp;
xp=0;
}
if (xpe > width) xpe=width;
while (xp++ < xpe) { BLEND_LINE(newfb, color); newfb++; }
if (d < 0) d += Eincr;
else
{
d += NEincr;
x1 += yincr;
offs += yincr;
}
offs += width;
y1++;
}
}
}
}
+604
View File
@@ -0,0 +1,604 @@
/*
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.
*/
#include <windows.h>
#include <math.h>
#include <process.h>
#include "draw.h"
#include "wnd.h"
#include "r_defs.h"
#include "render.h"
#include "vis.h"
#include "cfgwnd.h"
#include "resource.h"
#include "bpm.h"
#include "api.h"
#include "../winamp/wa_ipc.h"
#include "../Agave/Language/api_language.h"
#include <api/service/waServiceFactory.h>
#include <stdio.h>
#ifdef REAPLAY_PLUGIN
#include "../../jmde/reaper_plugin.h"
const char *(*get_ini_file)();
int (*vuGetVisData)(char *vdata, int size);
#endif
#define PLUGIN_VERSION "v2.93"
#include "avs_eelif.h"
extern void GetClientRect_adj(HWND hwnd, RECT *r);
static unsigned char g_logtab[256];
HINSTANCE g_hInstance;
/* char *verstr=
#ifndef LASER
"Advanced Visualization Studio"
#else
"AVS/Laser"
#endif
" v2.92"
;
*/
static unsigned int WINAPI RenderThread(LPVOID a);
static void config(struct winampVisModule *this_mod);
static int init(struct winampVisModule *this_mod);
static int render(struct winampVisModule *this_mod);
static void quit(struct winampVisModule *this_mod);
HANDLE g_hThread;
volatile int g_ThreadQuit;
static CRITICAL_SECTION g_cs;
static unsigned char g_visdata[2][2][576];
static int g_visdata_pstat;
/* wasabi based services for localisation support */
api_service *WASABI_API_SVC = 0;
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
static char module1[128];
static winampVisModule *getModule(int which);
static winampVisHeader hdr = { VIS_HDRVER, 0, getModule };
// use this to get our own HINSTACE since overriding DllMain(..) causes instant crashes (should see why)
static HINSTANCE GetMyInstance()
{
MEMORY_BASIC_INFORMATION mbi = {0};
if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
return (HINSTANCE)mbi.AllocationBase;
return NULL;
}
extern "C" {
__declspec( dllexport ) winampVisHeader* winampVisGetHeader(HWND hwndParent)
{
if(!WASABI_API_LNG_HINST)
{
// loader so that we can get the localisation service api for use
WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(GetMyInstance(),VisAVSLangGUID);
}
#ifndef LASER
static char szDescription[256];
wsprintfA(szDescription,"%s " PLUGIN_VERSION,WASABI_API_LNGSTRING_BUF(IDS_AVS,module1,128));
hdr.description = szDescription;
#else
hdr.description = "AVS/Laser "PLUGIN_VERSION;
#endif
return &hdr;
}
}
static winampVisModule *getModule(int which)
{
static winampVisModule mod =
{
#ifdef LASER
"Advanced Visualization Studio/Laser",
#else
module1,
#endif
NULL, // hwndParent
NULL, // hDllInstance
0, // sRate
0, // nCh
1000/70, // latencyMS
1000/70,// delayMS
2, // spectrumNch
2, // waveformNch
{ 0, }, // spectrumData
{ 0, }, // waveformData
config,
init,
render,
quit
};
if (which==0) return &mod;
return 0;
}
void about(HWND hwndParent)
{
static int about_here = 0;
char aboutbuf[1024] = {0}, aboutTitle[48] = {0};
if (about_here)
{
SetActiveWindow(FindWindow("#32770",WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48)));
return;
}
about_here = 1;
wsprintf(aboutbuf,WASABI_API_LNGSTRING(IDS_ABOUT_STRING),hdr.description);
MessageBox(hwndParent,aboutbuf,WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48),0);
about_here = 0;
}
HWND GetDialogBoxParent(HWND winamp)
{
HWND parent = (HWND)SendMessage(winamp, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
if (!parent || parent == (HWND)1)
return winamp;
return parent;
/*
BOOL CALLBACK aboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SetDlgItemText(hwndDlg,IDC_VERSTR,verstr);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK: case IDCANCEL:
EndDialog(hwndDlg,0);
return 0;
}
return 0;
}
return 0;
*/
}
static void config(struct winampVisModule *this_mod)
{
if (!g_hwnd || !IsWindow(g_hwnd))
{
about(GetDialogBoxParent(this_mod->hwndParent));
// DialogBox(this_mod->hDllInstance,MAKEINTRESOURCE(IDD_DIALOG2),this_mod->hwndParent,aboutProc);
}
else
{
SendMessage(g_hwnd,WM_USER+33,0,0);
}
}
CRITICAL_SECTION g_render_cs;
static int g_is_beat;
char g_path[1024];
int beat_peak1,beat_peak2, beat_cnt,beat_peak1_peak;
void main_setRenderThreadPriority()
{
int prios[]={
GetThreadPriority(GetCurrentThread()),
THREAD_PRIORITY_IDLE,
THREAD_PRIORITY_LOWEST,
THREAD_PRIORITY_NORMAL,
THREAD_PRIORITY_HIGHEST,
};
SetThreadPriority(g_hThread,prios[cfg_render_prio]);
}
extern void previous_preset(HWND hwnd);
extern void next_preset(HWND hwnd);
extern void random_preset(HWND hwnd);
#if 0//syntax highlighting
HINSTANCE hRich;
#endif
static int init(struct winampVisModule *this_mod)
{
DWORD id;
FILETIME ft;
#if 0//syntax highlighting
if (!hRich) hRich=LoadLibrary("RICHED32.dll");
#endif
GetSystemTimeAsFileTime(&ft);
srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
g_hInstance=this_mod->hDllInstance;
GetModuleFileName(g_hInstance,g_path,MAX_PATH);
char *p=g_path+strlen(g_path);
while (p > g_path && *p != '\\') p--;
*p = 0;
#ifdef WA2_EMBED
if (SendMessage(this_mod->hwndParent,WM_USER,0,0) < 0x2900)
{
char title[16];
MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_REQUIRES_2_9_PLUS),
WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
return 1;
}
#endif
#ifndef NO_MMX
extern int is_mmx(void);
if (!is_mmx())
{
char title[16];
MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_NO_MMX_SUPPORT),
WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
return 1;
}
#endif
#ifdef LASER
strcat(g_path,"\\avs_laser");
#else
strcat(g_path,"\\avs");
#endif
CreateDirectory(g_path,NULL);
InitializeCriticalSection(&g_cs);
InitializeCriticalSection(&g_render_cs);
g_ThreadQuit=0;
g_visdata_pstat=1;
AVS_EEL_IF_init();
if (Wnd_Init(this_mod)) return 1;
{
int x;
for (x = 0; x < 256; x ++)
{
double a=log((double)x*60.0/255.0 + 1.0)/log(60.0);
int t=(int)(a*255.0);
if (t<0)t=0;
if (t>255)t=255;
g_logtab[x]=(unsigned char )t;
}
}
initBpm();
Render_Init(g_hInstance);
CfgWnd_Create(this_mod);
g_hThread=(HANDLE)_beginthreadex(NULL,0,RenderThread,0,0,(unsigned int *)&id);
main_setRenderThreadPriority();
SetForegroundWindow(g_hwnd);
SetFocus(g_hwnd);
return 0;
}
static int render(struct winampVisModule *this_mod)
{
int x,avs_beat=0,b;
if (g_ThreadQuit) return 1;
EnterCriticalSection(&g_cs);
if (g_ThreadQuit)
{
LeaveCriticalSection(&g_cs);
return 1;
}
if (g_visdata_pstat)
for (x = 0; x< 576*2; x ++)
g_visdata[0][0][x]=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
else
{
for (x = 0; x < 576*2; x ++)
{
int t=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
if (g_visdata[0][0][x] < t)
g_visdata[0][0][x] = t;
}
}
memcpy(&g_visdata[1][0][0],this_mod->waveformData,576*2);
{
int lt[2]={0,0};
int x;
int ch;
for (ch = 0; ch < 2; ch ++)
{
unsigned char *f=(unsigned char*)&this_mod->waveformData[ch][0];
for (x = 0; x < 576; x ++)
{
int r= *f++^128;
r-=128;
if (r<0)r=-r;
lt[ch]+=r;
}
}
lt[0]=max(lt[0],lt[1]);
beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
beat_cnt++;
if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
{
if (beat_cnt>0)
{
beat_cnt=0;
avs_beat=1;
}
beat_peak1=(lt[0]+beat_peak1_peak)/2;
beat_peak1_peak=lt[0];
}
else if (lt[0] > beat_peak2)
{
beat_peak2=lt[0];
}
else beat_peak2=(beat_peak2*14)/16;
}
b=refineBeat(avs_beat);
if (b) g_is_beat=1;
g_visdata_pstat=0;
LeaveCriticalSection(&g_cs);
return 0;
}
static void quit(struct winampVisModule *this_mod)
{
#define DS(x)
//MessageBox(this_mod->hwndParent,x,"AVS Debug",MB_OK)
if (g_hThread)
{
DS("Waitin for thread to quit\n");
g_ThreadQuit=1;
if (WaitForSingleObject(g_hThread,10000) != WAIT_OBJECT_0)
{
DS("Terminated thread (BAD!)\n");
//MessageBox(NULL,"error waiting for thread to quit","a",MB_TASKMODAL);
TerminateThread(g_hThread,0);
}
DS("Thread done... calling ddraw_quit\n");
DDraw_Quit();
DS("Calling cfgwnd_destroy\n");
CfgWnd_Destroy();
DS("Calling render_quit\n");
Render_Quit(this_mod->hDllInstance);
DS("Calling wnd_quit\n");
Wnd_Quit();
DS("closing thread handle\n");
CloseHandle(g_hThread);
g_hThread=NULL;
DS("calling eel quit\n");
AVS_EEL_IF_quit();
DS("cleaning up critsections\n");
DeleteCriticalSection(&g_cs);
DeleteCriticalSection(&g_render_cs);
DS("smp_cleanupthreads\n");
C_RenderListClass::smp_cleanupthreads();
}
#undef DS
#if 0//syntax highlighting
if (hRich) FreeLibrary(hRich);
hRich=0;
#endif
}
#define FPS_NF 64
static unsigned int WINAPI RenderThread(LPVOID a)
{
int framedata[FPS_NF]={0,};
int framedata_pos=0;
int s=0;
char vis_data[2][2][576];
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
while (!g_ThreadQuit)
{
int w,h,*fb=NULL, *fb2=NULL,beat=0;
#ifdef REAPLAY_PLUGIN
if(!IsWindowVisible(g_hwnd))
{
Sleep(1);
continue;
}
char visdata[576*2*2];
int ret = vuGetVisData(visdata, sizeof(visdata));
if (!ret)
{
memset(&vis_data[0][0][0],0,576*2*2);
beat=0;
}
else
{
int x;
unsigned char *v=(unsigned char *)visdata;
for (x = 0; x < 576*2; x ++)
vis_data[0][0][x]=g_logtab[*v++];
for (x = 0; x < 576*2; x ++)
((unsigned char *)vis_data[1][0])[x]=*v++;
v=(unsigned char *)visdata+1152;
{
int lt[2]={0,0};
int ch;
for (ch = 0; ch < 2; ch ++)
{
for (x = 0; x < 576; x ++)
{
int r=*v++^128;
r-=128;
if (r<0)r=-r;
lt[ch]+=r;
}
}
lt[0]=max(lt[0],lt[1]);
beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
beat_cnt++;
if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
{
if (beat_cnt>0)
{
beat_cnt=0;
beat=1;
}
beat_peak1=(lt[0]+beat_peak1_peak)/2;
beat_peak1_peak=lt[0];
}
else if (lt[0] > beat_peak2)
{
beat_peak2=lt[0];
}
else beat_peak2=(beat_peak2*14)/16;
}
// EnterCriticalSection(&g_title_cs);
beat=refineBeat(beat);
// LeaveCriticalSection(&g_title_cs);
}
#else
EnterCriticalSection(&g_cs);
memcpy(&vis_data[0][0][0],&g_visdata[0][0][0],576*2*2);
g_visdata_pstat=1;
beat=g_is_beat;
g_is_beat=0;
LeaveCriticalSection(&g_cs);
#endif
if (!g_ThreadQuit)
{
if (IsWindow(g_hwnd)&&!g_in_destroy) DDraw_Enter(&w,&h,&fb,&fb2);
else break;
if (fb&&fb2)
{
extern int g_dlg_w, g_dlg_h, g_dlg_fps;
#ifdef LASER
g_laser_linelist->ClearLineList();
#endif
EnterCriticalSection(&g_render_cs);
int t=g_render_transition->render(vis_data,beat,s?fb2:fb,s?fb:fb2,w,h);
LeaveCriticalSection(&g_render_cs);
if (t&1) s^=1;
#ifdef LASER
s=0;
memset(fb,0,w*h*sizeof(int));
LineDrawList(g_laser_linelist,fb,w,h);
#endif
if (IsWindow(g_hwnd)) DDraw_Exit(s);
int lastt=framedata[framedata_pos];
int thist=GetTickCount();
framedata[framedata_pos]=thist;
g_dlg_w=w;
g_dlg_h=h;
if (lastt)
{
g_dlg_fps=MulDiv(sizeof(framedata)/sizeof(framedata[0]),10000,thist-lastt);
}
framedata_pos++;
if (framedata_pos >= sizeof(framedata)/sizeof(framedata[0])) framedata_pos=0;
}
int fs=DDraw_IsFullScreen();
int sv=(fs?(cfg_speed>>8):cfg_speed)&0xff;
Sleep(min(max(sv,1),100));
}
}
_endthreadex(0);
return 0;
}
#ifdef REAPLAY_PLUGIN
static winampVisModule dummyMod;
extern "C"
{
REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t *rec)
{
g_hInstance=hInstance;
if (rec)
{
if (rec->caller_version != REAPER_PLUGIN_VERSION || !rec->GetFunc)
return 0;
*((void **)&get_ini_file) = rec->GetFunc("get_ini_file");
*((void **)&vuGetVisData) = rec->GetFunc("vuGetVisData");
if (!get_ini_file || !vuGetVisData)
return 0;
dummyMod.hwndParent=rec->hwnd_main;
dummyMod.hDllInstance=g_hInstance;
init(&dummyMod);
return 1;
}
else
{
quit(&dummyMod);
return 0;
}
}
};
#endif
@@ -0,0 +1,74 @@
/*
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.
*/
#include <windows.h>
#include <math.h>
#include "r_defs.h"
void matrixRotate(float matrix[], char m, float Deg) {
char m1, m2;
float c,s;
Deg *= 3.141592653589f / 180.0f;
memset(matrix,0,sizeof(float)*16);
matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0f;
m1 = (m % 3);
m2 = ((m1+1) % 3);
c = (float)cos(Deg); s = (float)sin(Deg);
matrix[(m1<<2)+m1]=c; matrix[(m1<<2)+m2]=s;
matrix[(m2<<2)+m2]=c; matrix[(m2<<2)+m1]=-s;
}
void matrixTranslate(float m[], float x, float y, float z) {
memset(m,0,sizeof(float)*16);
m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0f;
m[0+3] = x; m[4+3] = y; m[8+3] = z;
}
void matrixMultiply(float *dest, float src[]) {
float temp[16];
int i;
memcpy(temp,dest,sizeof(float)*16);
for (i = 0; i < 16; i += 4) {
*dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+
src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0];
*dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+
src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1];
*dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+
src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2];
*dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+
src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3];
}
}
void matrixApply(float *m, float x, float y, float z,
float *outx, float *outy, float *outz) {
*outx = x*m[0] + y*m[1] + z*m[2] + m[3];
*outy = x*m[4] + y*m[5] + z*m[6] + m[7];
*outz = x*m[8] + y*m[9] + z*m[10] + m[11];
}
@@ -0,0 +1,5 @@
Movement help goes here (send me some :) )
To use the custom table, modify r,d,x or y.
Rect coords: x,y are in (-1..1) . Otherwise: d is (0..1) and r is (0..2PI).
You can also access 'sw' and 'sh' for screen dimensions in pixels (might be useful)
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+383
View File
@@ -0,0 +1,383 @@
/*
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.
*/
#include <windows.h>
#include <stdlib.h>
#include <vfw.h>
#include <commctrl.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define MOD_NAME "Render / AVI"
#define C_THISCLASS C_AVIClass
class C_THISCLASS : public C_RBASE {
protected:
public:
C_THISCLASS();
void reinit(int, int);
void loadAvi(char *name);
void closeAvi(void);
virtual ~C_THISCLASS();
virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_AVI,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int enabled;
char ascName[MAX_PATH];
int lastWidth, lastHeight;
HDRAWDIB hDrawDib;
PAVISTREAM PAVIVideo;
PGETFRAME PgetFrame;
HBITMAP hRetBitmap;
HBITMAP hOldBitmap;
HDC hDesktopDC;
HDC hBitmapDC;
LPBITMAPINFOHEADER lpFrame;
BITMAPINFO bi;
int blend, blendavg, adapt, persist;
int loaded, rendering;
int lFrameIndex;
int length;
unsigned int speed;
unsigned int lastspeed;
int *old_image,old_image_w,old_image_h;
};
static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
// configuration read/write
C_THISCLASS::C_THISCLASS() // set up default configuration
{
AVIFileInit ( ) ;
hDrawDib = DrawDibOpen ( ) ;
lastWidth=0;
lastHeight=0;
lFrameIndex=0;
loaded=0;
rendering=0;
length=0;
blend=0;
adapt=0;
blendavg=1;
persist=6;
enabled=1;
speed=0;
lastspeed=0;
old_image=NULL; old_image_h=0; old_image_w=0;
}
C_THISCLASS::~C_THISCLASS()
{
closeAvi();
SelectObject (hBitmapDC, hOldBitmap);
DeleteDC (hBitmapDC);
ReleaseDC (NULL, hDesktopDC);
AVIFileExit ( );
DrawDibClose (hDrawDib);
if(old_image) {
GlobalFree(old_image);
old_image=NULL;
old_image_h=old_image_w=0;
}
}
void C_THISCLASS::loadAvi(char *name)
{
char pathfile[MAX_PATH];
if (loaded) closeAvi();
wsprintf(pathfile,"%s\\%s",g_path, name);
if (AVIStreamOpenFromFile ((PAVISTREAM FAR *) &PAVIVideo, pathfile, streamtypeVIDEO, 0, OF_READ | OF_SHARE_EXCLUSIVE, NULL) != 0)
{
// MessageBox(NULL, "An error occured while trying to open a file. Effect is disabled", "Warning", 0);
return;
}
PgetFrame = AVIStreamGetFrameOpen (PAVIVideo, NULL);
length = AVIStreamLength(PAVIVideo);
lFrameIndex = 0;
lpFrame = (LPBITMAPINFOHEADER) AVIStreamGetFrame (PgetFrame, 0);
reinit(lastWidth, lastHeight);
loaded=1;
}
void C_THISCLASS::closeAvi(void)
{
if (loaded)
{
while (rendering);
loaded=0;
AVIStreamGetFrameClose (PgetFrame);
AVIStreamRelease (PAVIVideo);
}
}
#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) // read configuration of max length "len" from data.
{
int pos=0;
char *p=ascName;
if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
while (data[pos] && len-pos > 0 && p-ascName < sizeof(ascName)-1) *p++=data[pos++];
*p=0; pos++;
if (len-pos >= 4) { adapt=GET_INT(); pos+=4; }
if (len-pos >= 4) { persist=GET_INT(); pos+=4; }
if (len-pos >= 4) { speed=GET_INT(); pos+=4; }
if (*ascName)
loadAvi(ascName);
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(blendavg); pos+=4;
strcpy((char *)data+pos, ascName);
pos+=strlen(ascName)+1;
PUT_INT(adapt); pos+=4;
PUT_INT(persist); pos+=4;
PUT_INT(speed); pos+=4;
return pos;
}
void C_THISCLASS::reinit(int w, int h)
{
if (lastWidth || lastHeight)
{
SelectObject (hBitmapDC, hOldBitmap);
DeleteDC (hBitmapDC);
ReleaseDC (NULL, hDesktopDC);
}
hDesktopDC = GetDC (NULL);
hRetBitmap = CreateCompatibleBitmap (hDesktopDC, w, h);
hBitmapDC = CreateCompatibleDC (hDesktopDC);
hOldBitmap = (HBITMAP) SelectObject (hBitmapDC, hRetBitmap);
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = w;
bi.bmiHeader.biHeight = h;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int *p,*d;
int i,j;
static int persistCount=0;
if (!enabled || !loaded) return 0;
if(h!=old_image_h||w!=old_image_w) {
if(old_image)
GlobalFree(old_image);
old_image=(int *)GlobalAlloc(GMEM_FIXED,sizeof(int)*w*h);
old_image_h=h; old_image_w=w;
}
if((lastspeed+speed)>GetTickCount()) {
memcpy(fbout,old_image,sizeof(int)*w*h);
} else {
lastspeed=GetTickCount();
rendering=1;
if (lastWidth != w || lastHeight != h)
{
lastWidth = w;
lastHeight = h;
reinit(w, h);
}
if (isBeat&0x80000000) return 0;
if (!length) return 0;
lFrameIndex %= length;
lpFrame = (LPBITMAPINFOHEADER) AVIStreamGetFrame (PgetFrame, lFrameIndex++);
DrawDibDraw (hDrawDib, hBitmapDC, 0, 0, lastWidth, lastHeight, lpFrame,
NULL, 0, 0, (int) lpFrame ->biWidth, (int) lpFrame ->biHeight, 0);
GetDIBits(hBitmapDC, hRetBitmap, 0, h, (void *)fbout, &bi, DIB_RGB_COLORS);
rendering=0;
memcpy(old_image,fbout,sizeof(int)*w*h);
}
if (isBeat)
persistCount=persist;
else
if (persistCount>0) persistCount--;
p = fbout;
d = framebuffer+w*(h-1);
if (blend || (adapt && (isBeat || persistCount)))
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
{
*d=BLEND(*p, *d);
d++;
p++;
}
d -= w*2;
}
else
if (blendavg || adapt)
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
{
*d=BLEND_AVG(*p, *d);
d++;
p++;
}
d -= w*2;
}
else
for (i=0;i<h;i++)
{
memcpy(d, p, w*4);
p+=w;
d-=w;
}
return 0;
}
// configuration dialog stuff
static void EnableWindows(HWND hwndDlg)
{
EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST),g_ConfigThis->adapt);
EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST_TITLE),g_ConfigThis->adapt);
}
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETRANGE, TRUE, MAKELONG(0, 32));
SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETPOS, TRUE, g_ConfigThis->persist);
SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETTICFREQ, 50, 0);
SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(0, 1000));
SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, g_ConfigThis->speed);
if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
if (g_ConfigThis->adapt) CheckDlgButton(hwndDlg,IDC_ADAPT,BST_CHECKED);
if (!g_ConfigThis->adapt && !g_ConfigThis->blend && !g_ConfigThis->blendavg)
CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
EnableWindows(hwndDlg);
loadComboBox(GetDlgItem(hwndDlg,OBJ_COMBO),"*.AVI",g_ConfigThis->ascName);
return 1;
case WM_NOTIFY:
{
if (LOWORD(wParam) == IDC_PERSIST)
g_ConfigThis->persist = SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_GETPOS, 0, 0);
if (LOWORD(wParam) == IDC_SPEED)
g_ConfigThis->speed = SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0);
}
case WM_COMMAND:
if ((LOWORD(wParam) == IDC_CHECK1) ||
(LOWORD(wParam) == IDC_ADDITIVE) ||
(LOWORD(wParam) == IDC_REPLACE) ||
(LOWORD(wParam) == IDC_ADAPT) ||
(LOWORD(wParam) == IDC_5050) )
{
g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
g_ConfigThis->adapt=IsDlgButtonChecked(hwndDlg,IDC_ADAPT)?1:0;
EnableWindows(hwndDlg);
}
if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == OBJ_COMBO) // handle clicks to combo box
{
int sel = SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETCURSEL, 0, 0);
if (sel != -1)
{
SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETLBTEXT, sel, (LPARAM)g_ConfigThis->ascName);
if (*(g_ConfigThis->ascName))
g_ConfigThis->loadAvi(g_ConfigThis->ascName);
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_AVI,hwndParent,g_DlgProc);
}
// export stuff
C_RBASE *R_AVI(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
#else//!LASER
C_RBASE *R_AVI(char *desc) { return NULL; }
#endif
@@ -0,0 +1,557 @@
/*
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
// highly optimized on 10/10/00 JF. MMX.
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_BlitClass
#define MOD_NAME "Trans / Blitter Feedback"
static const unsigned int revn[2]={0xff00ff,0xff00ff};//{0x1000100,0x1000100}; <<- this is actually more correct, but we're going for consistency vs. the non-mmx ver-jf
static const int zero=0;
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BLITTER_FEEDBACK,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int scale, scale2, blend,beatch;
int fpos;
int subpixel;
int blitter_normal(int *framebuffer, int *fbout, int w, int h, int f_val);
int blitter_out(int *framebuffer, int *fbout, int w, int h, int f_val);
};
#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) { scale=GET_INT(); pos+=4; }
if (len-pos >= 4) { scale2=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { beatch=GET_INT(); pos+=4; }
if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
else subpixel=0;
fpos=scale;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(scale); pos+=4;
PUT_INT(scale2); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(beatch); pos+=4;
PUT_INT(subpixel); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
scale=30;
scale2=30;
blend=0;
fpos=scale;
beatch=0;
subpixel=1;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::blitter_out(int *framebuffer, int *fbout, int w, int h, int f_val)
{
const int adj=7;
int ds_x = ((f_val+(1<<adj)-32)<<(16-adj));
int x_len=((w<<16)/ds_x)&~3;
int y_len=(h<<16)/ds_x;
if (x_len >= w || y_len >= h) return 0;
int start_x=(w-x_len)/2;
int start_y=(h-y_len)/2;
int s_y=32768;
int *dest=(int *)framebuffer+start_y*w + start_x;
int *src=(int *)fbout+start_y*w + start_x;
int y;
fbout += start_y*w;
for (y = 0; y < y_len; y ++)
{
int s_x=32768;
unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
unsigned int *old_dest=((unsigned int *)fbout) + start_x;
s_y+=ds_x;
if (!blend)
{
int x=x_len/4;
while (x--)
{
old_dest[0]=src[s_x>>16];
s_x += ds_x;
old_dest[1]=src[s_x>>16];
s_x += ds_x;
old_dest[2]=src[s_x>>16];
s_x += ds_x;
old_dest[3]=src[s_x>>16];
s_x += ds_x;
old_dest+=4;
}
}
else
{
unsigned int *s2=(unsigned int *)framebuffer+((y+start_y)*w)+start_x;
int x=x_len/4;
while (x--)
{
old_dest[0]=BLEND_AVG(s2[0],src[s_x>>16]);
s_x += ds_x;
old_dest[1]=BLEND_AVG(s2[1],src[s_x>>16]);
s_x += ds_x;
old_dest[2]=BLEND_AVG(s2[2],src[s_x>>16]);
s_x += ds_x;
old_dest[3]=BLEND_AVG(s2[3],src[s_x>>16]);
s2+=4;
old_dest+=4;
s_x += ds_x;
}
}
fbout += w;
}
for (y = 0; y < y_len; y ++)
{
memcpy(dest,src,x_len*sizeof(int));
dest+=w;
src+=w;
}
return 0;
}
int C_THISCLASS::blitter_normal(int *framebuffer, int *fbout, int w, int h, int f_val)
{
int ds_x = ((f_val+32)<<16)/64;
int isx=(((w<<16)-((ds_x*w)))/2);
int s_y=(((h<<16)-((ds_x*h)))/2);
if (subpixel)
{
int y;
for (y = 0; y < h; y ++)
{
int s_x=isx;
unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
int ypart=(s_y>>8)&0xff;
s_y+=ds_x;
#ifdef NO_MMX
{
ypart=(ypart*255)>>8;
int x=w/4;
while (x--)
{
fbout[0]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
s_x += ds_x;
fbout[1]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
s_x += ds_x;
fbout[2]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
s_x += ds_x;
fbout[3]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
s_x += ds_x;
fbout+=4;
}
}
#else
{
__int64 mem5,mem7;
__asm
{
mov edi, fbout
mov esi, w
movd mm7, ypart
punpcklwd mm7,mm7
movq mm5, revn
punpckldq mm7,mm7
psubw mm5, mm7
mov ecx, esi
movq mem5,mm5
movq mem7,mm7
shr ecx, 1
mov edx, s_x
align 16
mmx_scale_loop1:
mov ebx, edx
mov eax, edx
shr eax, 14
add edx, ds_x
shr ebx, 8
and eax, ~3
add eax, src
and ebx, 0xff
movd mm6, ebx
//
movq mm4, revn
punpcklwd mm6,mm6
movd mm0, [eax]
punpckldq mm6,mm6
movd mm1, [eax+4]
psubw mm4, mm6
movd mm2, [eax+esi*4]
punpcklbw mm0, [zero]
movd mm3, [eax+esi*4+4]
pmullw mm0, mm4 // mm0 used in divide for 3 cycles
punpcklbw mm1, [zero]
mov eax, edx
pmullw mm1, mm6 // mm1 used in divide for 3 cycles
punpcklbw mm2, [zero]
pmullw mm2, mm4 // mm2 used in divide for 3 cycles
punpcklbw mm3, [zero]
pmullw mm3, mm6 // mm3 used in divide for 3 cycles
shr eax, 14
mov ebx, edx
and eax, ~3
paddw mm0, mm1
shr ebx, 8
psrlw mm0, 8
add eax, src
paddw mm2, mm3
and ebx, 0xff
pmullw mm0, mem5
psrlw mm2, 8
pmullw mm2, mem7
add edx, ds_x
movd mm6, ebx
//
movq mm4, revn
punpcklwd mm6,mm6
movd mm1, [eax+4]
//
movd mm7, [eax+esi*4]
paddw mm0, mm2
movd mm5, [eax]
psrlw mm0, 8
movd mm3, [eax+esi*4+4]
packuswb mm0, mm0
movd [edi], mm0
punpckldq mm6,mm6
//poop
punpcklbw mm5, [zero]
psubw mm4, mm6
punpcklbw mm1, [zero]
pmullw mm5, mm4
punpcklbw mm7, [zero]
pmullw mm1, mm6
punpcklbw mm3, [zero]
pmullw mm7, mm4
//cycle
//cycle
paddw mm5, mm1
//
pmullw mm3, mm6
psrlw mm5, 8
pmullw mm5, mem5
add edi, 8
// cycle
// cycle
paddw mm7, mm3
//
psrlw mm7, 8
//
pmullw mm7, mem7
dec ecx
// cycle
// cycle
// cycle
paddw mm5, mm7
psrlw mm5, 8
packuswb mm5, mm5
movd [edi-4], mm5
jnz mmx_scale_loop1
mov fbout, edi
}
} // end mmx
__asm emms;
#endif
if (blend) // reblend this scanline with the original
{
fbout-=w;
int x=w/4;
unsigned int *s2=(unsigned int *)framebuffer+y*w;
while (x--)
{
fbout[0]=BLEND_AVG(fbout[0],s2[0]);
fbout[1]=BLEND_AVG(fbout[1],s2[1]);
fbout[2]=BLEND_AVG(fbout[2],s2[2]);
fbout[3]=BLEND_AVG(fbout[3],s2[3]);
fbout+=4;
s2+=4;
}
}
} // end subpixel y loop
}
else // !subpixel
{
int y;
for (y = 0; y < h; y ++)
{
int s_x=isx;
unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
int ypart=(s_y>>8)&0xff;
s_y+=ds_x;
if (!blend)
{
int x=w/4;
while (x--)
{
fbout[0]=src[s_x>>16];
s_x += ds_x;
fbout[1]=src[s_x>>16];
s_x += ds_x;
fbout[2]=src[s_x>>16];
s_x += ds_x;
fbout[3]=src[s_x>>16];
s_x += ds_x;
fbout+=4;
}
}
else
{
unsigned int *s2=(unsigned int *)framebuffer+(y*w);
int x=w/4;
while (x--)
{
fbout[0]=BLEND_AVG(s2[0],src[s_x>>16]);
s_x += ds_x;
fbout[1]=BLEND_AVG(s2[1],src[s_x>>16]);
s_x += ds_x;
fbout[2]=BLEND_AVG(s2[2],src[s_x>>16]);
s_x += ds_x;
fbout[3]=BLEND_AVG(s2[3],src[s_x>>16]);
s2+=4;
fbout+=4;
s_x += ds_x;
}
}
}
}
return 1;
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (isBeat&0x80000000) return 0;
int f_val;
unsigned int *dest=(unsigned int *) fbout;
if (isBeat && beatch)
{
fpos=scale2;
}
if (scale < scale2)
{
f_val=(fpos > scale? fpos:scale);
fpos -= 3;
}
else
{
f_val=(fpos < scale? fpos :scale);
fpos+=3;
}
if (f_val<0) f_val=0;
if (f_val < 32) return blitter_normal(framebuffer,fbout,w,h,f_val);
if (f_val > 32) return blitter_out(framebuffer,fbout,w,h,f_val);
return 0;
}
C_RBASE *R_BlitterFB(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,256);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->scale);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,256);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->scale2);
if (g_this->blend==1) CheckDlgButton(hwndDlg,IDC_BLEND,BST_CHECKED);
if (g_this->subpixel) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
if (g_this->beatch==1) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BLEND:
if (IsDlgButtonChecked(hwndDlg,IDC_BLEND))
{
g_this->blend=1;
}
else g_this->blend=0;
break;
case IDC_CHECK1:
if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1))
g_this->beatch=1;
else g_this->beatch=0;
break;
case IDC_CHECK2:
if (IsDlgButtonChecked(hwndDlg,IDC_CHECK2))
{
g_this->subpixel=1;
}
else g_this->subpixel=0;
break;
}
return 0;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->scale=t;
g_this->fpos=t;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
{
g_this->scale2=t;
g_this->fpos=t;
}
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BLT,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_BlitterFB(char *desc) { return NULL; }
#endif
@@ -0,0 +1,883 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_BlurClass
#define MOD_NAME "Trans / Blur"
static const int zero=0;
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BLUR,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
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
int enabled;
int roundmode;
};
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { roundmode=GET_INT(); pos+=4; }
else roundmode=0;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(roundmode); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
roundmode=0;
enabled=1;
}
C_THISCLASS::~C_THISCLASS()
{
}
#define MASK_SH1 (~(((1<<7)|(1<<15)|(1<<23))<<1))
#define MASK_SH2 (~(((3<<6)|(3<<14)|(3<<22))<<2))
#define MASK_SH3 (~(((7<<5)|(7<<13)|(7<<21))<<3))
#define MASK_SH4 (~(((15<<4)|(15<<12)|(15<<20))<<4))
static unsigned int mmx_mask1[2]={MASK_SH1,MASK_SH1};
static unsigned int mmx_mask2[2]={MASK_SH2,MASK_SH2};
static unsigned int mmx_mask3[2]={MASK_SH3,MASK_SH3};
static unsigned int mmx_mask4[2]={MASK_SH4,MASK_SH4};
#define DIV_2(x) ((( x ) & MASK_SH1)>>1)
#define DIV_4(x) ((( x ) & MASK_SH2)>>2)
#define DIV_8(x) ((( x ) & MASK_SH3)>>3)
#define DIV_16(x) ((( x ) & MASK_SH4)>>4)
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 (!enabled) return;
timingEnter(0);
unsigned int *f = (unsigned int *) framebuffer;
unsigned int *of = (unsigned int *) fbout;
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;
f += skip_pix;
of+= skip_pix;
int at_top=0, at_bottom=0;
if (!this_thread) at_top=1;
if (this_thread >= max_threads - 1) at_bottom=1;
if (enabled == 2)
{
// top line
if (at_top)
{
unsigned int *f2=f+w;
int x;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x03030303; adj_tl2 = 0x04040404; }
// top left
*of++=DIV_2(f[0])+DIV_4(f[0])+DIV_8(f[1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
// top center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
of[1]=DIV_2(f[1]) + DIV_8(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + adj_tl2;
of[2]=DIV_2(f[2]) + DIV_8(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + adj_tl2;
of[3]=DIV_2(f[3]) + DIV_8(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + adj_tl2;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
f++;
f2++;
}
// top right
*of++=DIV_2(f[0])+DIV_4(f[0]) + DIV_8(f[-1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
}
// middle block
{
int y=outh-at_top-at_bottom;
unsigned int adj_tl1=0,adj_tl2=0;
unsigned __int64 adj2=0;
if (roundmode) { adj_tl1=0x04040404; adj_tl2=0x05050505; adj2=0x0505050505050505i64; }
while (y--)
{
int x;
unsigned int *f2=f+w;
unsigned int *f3=f-w;
// left edge
*of++=DIV_2(f[0])+DIV_8(f[0])+DIV_8(f[1])+DIV_8(f2[0])+DIV_8(f3[0])+adj_tl1; f++; f2++; f3++;
// middle of line
#ifdef NO_MMX
x=(w-2)/4;
if (roundmode)
{
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]) + 0x05050505;
of[1]=DIV_2(f[1]) + DIV_4(f[1]) + DIV_16(f[2]) + DIV_16(f[0]) + DIV_16(f2[1]) + DIV_16(f3[1]) + 0x05050505;
of[2]=DIV_2(f[2]) + DIV_4(f[2]) + DIV_16(f[3]) + DIV_16(f[1]) + DIV_16(f2[2]) + DIV_16(f3[2]) + 0x05050505;
of[3]=DIV_2(f[3]) + DIV_4(f[3]) + DIV_16(f[4]) + DIV_16(f[2]) + DIV_16(f2[3]) + DIV_16(f3[3]) + 0x05050505;
f+=4;
f2+=4;
f3+=4;
of+=4;
}
}
else
{
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]);
of[1]=DIV_2(f[1]) + DIV_4(f[1]) + DIV_16(f[2]) + DIV_16(f[0]) + DIV_16(f2[1]) + DIV_16(f3[1]);
of[2]=DIV_2(f[2]) + DIV_4(f[2]) + DIV_16(f[3]) + DIV_16(f[1]) + DIV_16(f2[2]) + DIV_16(f3[2]);
of[3]=DIV_2(f[3]) + DIV_4(f[3]) + DIV_16(f[4]) + DIV_16(f[2]) + DIV_16(f2[3]) + DIV_16(f3[3]);
f+=4;
f2+=4;
f3+=4;
of+=4;
}
}
#else
{
__asm
{
mov ecx, w
mov edx, ecx
mov ebx, edx
neg ebx
mov esi, f
mov edi, of
sub ecx, 2
shr ecx, 2
movq mm1, [esi-4]
align 16
mmx_light_blur_loop:
movq mm0, [esi]
movq mm2, [esi+4]
pand mm0, mmx_mask1
movq mm5, mm2
psrl mm0, 1
movq mm7, [esi+8]
movq mm4, mm0
pand mm1, mmx_mask4
pand mm4, mmx_mask1
movq mm3, [esi+edx*4]
psrl mm4, 1
paddb mm0, mm4
pand mm2, mmx_mask4
movq mm4, [esi+ebx*4]
pand mm3, mmx_mask4
pand mm4, mmx_mask4
psrl mm1, 4
pand mm7, mmx_mask1
movq mm6, [esi+12]
psrl mm2, 4
add esi, 16
psrl mm3, 4
paddb mm0, mm1
psrl mm4, 4
movq mm1, mm6
psrl mm7, 1
paddb mm2, mm3
paddb mm0, mm4
movq mm3, [esi+edx*4-8]
paddb mm0, mm2
movq mm4, [esi+ebx*4-8]
paddb mm0, [adj2]
pand mm6, mmx_mask4
movq [edi],mm0
pand mm5, mmx_mask4
movq mm0, mm7
pand mm3, mmx_mask4
psrl mm6, 4
pand mm0, mmx_mask1
pand mm4, mmx_mask4
psrl mm5, 4
psrl mm0, 1
paddb mm7, mm6
paddb mm7, mm0
add edi, 16
psrl mm3, 4
psrl mm4, 4
paddb mm5, mm3
paddb mm7, mm4
dec ecx
paddb mm7, mm5
paddb mm7, [adj2]
movq [edi-8],mm7
jnz mmx_light_blur_loop
mov of, edi
mov f, esi
};
f2=f+w; // update these bitches
f3=f-w;
}
#endif
x=(w-2)&3;
while (x--)
{
*of++=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]) + adj_tl2;
f++;
f2++;
f3++;
}
// right block
*of++=DIV_2(f[0])+DIV_8(f[0])+DIV_8(f[-1])+DIV_8(f2[0])+DIV_8(f3[0])+adj_tl1; f++;
}
}
// bottom block
if (at_bottom)
{
unsigned int *f2=f-w;
int x;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x03030303; adj_tl2 = 0x04040404; }
// bottom left
*of++=DIV_2(f[0])+DIV_4(f[0])+DIV_8(f[1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
// bottom center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
of[1]=DIV_2(f[1]) + DIV_8(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + adj_tl2;
of[2]=DIV_2(f[2]) + DIV_8(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2])+adj_tl2;
of[3]=DIV_2(f[3]) + DIV_8(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3])+adj_tl2;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0])+adj_tl2;
f++;
f2++;
}
// bottom right
*of++=DIV_2(f[0])+DIV_4(f[0]) + DIV_8(f[-1])+DIV_8(f2[0])+adj_tl; f++; f2++;
}
}
else if (enabled == 3) // more blur
{
// top line
if (at_top) {
unsigned int *f2=f+w;
int x;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x01010101; }
// top left
*of++=DIV_2(f[1])+DIV_2(f2[0]) + adj_tl2; f++; f2++;
// top center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0]) + adj_tl;
of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_2(f2[1]) +adj_tl;
of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_2(f2[2]) + adj_tl;
of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_2(f2[3]) + adj_tl;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
f++;
f2++;
}
// top right
*of++=DIV_2(f[-1])+DIV_2(f2[0])+adj_tl2; f++; f2++;
}
// middle block
{
int y=outh-at_top-at_bottom;
int adj_tl1=0,adj_tl2=0;
unsigned __int64 adj2=0;
if (roundmode) { adj_tl1=0x02020202; adj_tl2=0x03030303; adj2=0x0303030303030303i64; }
while (y--)
{
int x;
unsigned int *f2=f+w;
unsigned int *f3=f-w;
// left edge
*of++=DIV_2(f[1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++; f2++; f3++;
// middle of line
#ifdef NO_MMX
x=(w-2)/4;
if (roundmode)
{
while (x--)
{
of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]) + 0x03030303;
of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + DIV_4(f3[1]) + 0x03030303;
of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + DIV_4(f3[2]) + 0x03030303;
of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + DIV_4(f3[3]) + 0x03030303;
f+=4; f2+=4; f3+=4; of+=4;
}
}
else
{
while (x--)
{
of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]);
of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + DIV_4(f3[1]);
of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + DIV_4(f3[2]);
of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + DIV_4(f3[3]);
f+=4; f2+=4; f3+=4; of+=4;
}
}
#else
{
__asm
{
mov ecx, w
mov edx, ecx
mov ebx, edx
neg ebx
mov esi, f
mov edi, of
sub ecx, 2
shr ecx, 2
movq mm1, [esi-4]
align 16
mmx_heavy_blur_loop:
movq mm2, [esi+4]
pxor mm0, mm0
movq mm5, mm2
pxor mm7, mm7
movq mm3, [esi+edx*4]
pand mm1, mmx_mask2
movq mm4, [esi+ebx*4]
pand mm2, mmx_mask2
pand mm3, mmx_mask2
pand mm4, mmx_mask2
psrl mm1, 2
movq mm6, [esi+12]
psrl mm2, 2
psrl mm3, 2
paddb mm0, mm1
psrl mm4, 2
movq mm1, mm6
paddb mm2, mm3
paddb mm0, mm4
movq mm3, [esi+edx*4+8]
paddb mm0, mm2
movq mm4, [esi+ebx*4+8]
paddb mm0, [adj2]
pand mm6, mmx_mask2
movq [edi],mm0
pand mm5, mmx_mask2
pand mm3, mmx_mask2
add esi, 16
psrl mm6, 2
pand mm4, mmx_mask2
psrl mm5, 2
paddb mm7, mm6
psrl mm3, 2
add edi, 16
psrl mm4, 2
paddb mm5, mm3
paddb mm7, mm4
paddb mm7, mm5
paddb mm7, [adj2]
movq [edi-8],mm7
dec ecx
jnz mmx_heavy_blur_loop
mov of, edi
mov f, esi
};
f2=f+w; // update these bitches
f3=f-w;
}
#endif
x=(w-2)&3;
while (x--)
{
*of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]) + adj_tl2;
f++;
f2++;
f3++;
}
// right block
*of++=DIV_2(f[-1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++;
}
}
// bottom block
if (at_bottom)
{
unsigned int *f2=f-w;
int x;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x01010101; }
// bottom left
*of++=DIV_2(f[1])+DIV_2(f2[0]) + adj_tl2; f++; f2++;
// bottom center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_2(f2[1])+adj_tl;
of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_2(f2[2])+adj_tl;
of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_2(f2[3])+adj_tl;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
f++;
f2++;
}
// bottom right
*of++=DIV_2(f[-1])+DIV_2(f2[0])+adj_tl2; f++; f2++;
}
}
else
{
// top line
if (at_top)
{
unsigned int *f2=f+w;
int x;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x03030303; }
// top left
*of++=DIV_2(f[0])+DIV_4(f[1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
// top center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
of[1]=DIV_4(f[1]) + DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + adj_tl2;
of[2]=DIV_4(f[2]) + DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + adj_tl2;
of[3]=DIV_4(f[3]) + DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + adj_tl2;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
f++;
f2++;
}
// top right
*of++=DIV_2(f[0])+DIV_4(f[-1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
}
// middle block
{
int y=outh-at_top-at_bottom;
int adj_tl1=0,adj_tl2=0;
unsigned __int64 adj2=0;
if (roundmode) { adj_tl1=0x03030303; adj_tl2=0x04040404; adj2=0x0404040404040404i64; }
while (y--)
{
int x;
unsigned int *f2=f+w;
unsigned int *f3=f-w;
// left edge
*of++=DIV_4(f[0])+DIV_4(f[1])+DIV_4(f2[0])+DIV_4(f3[0])+adj_tl1; f++; f2++; f3++;
// middle of line
#ifdef NO_MMX
x=(w-2)/4;
if (roundmode)
{
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]) + 0x04040404;
of[1]=DIV_2(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + DIV_8(f3[1]) + 0x04040404;
of[2]=DIV_2(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + DIV_8(f3[2]) + 0x04040404;
of[3]=DIV_2(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + DIV_8(f3[3]) + 0x04040404;
f+=4; f2+=4; f3+=4; of+=4;
}
}
else
{
while (x--)
{
of[0]=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]);
of[1]=DIV_2(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + DIV_8(f3[1]);
of[2]=DIV_2(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + DIV_8(f3[2]);
of[3]=DIV_2(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + DIV_8(f3[3]);
f+=4; f2+=4; f3+=4; of+=4;
}
}
#else
{
__asm
{
mov ecx, w
mov edx, ecx
mov ebx, edx
neg ebx
mov esi, f
mov edi, of
sub ecx, 2
shr ecx, 2
movq mm1, [esi-4]
align 16
mmx_normal_blur_loop:
movq mm0, [esi]
movq mm2, [esi+4]
pand mm0, mmx_mask1
movq mm5, mm2
movq mm7, [esi+8]
pand mm1, mmx_mask3
movq mm3, [esi+edx*4]
pand mm2, mmx_mask3
movq mm4, [esi+ebx*4]
pand mm3, mmx_mask3
psrl mm0, 1
pand mm4, mmx_mask3
psrl mm1, 3
pand mm7, mmx_mask1
movq mm6, [esi+12]
psrl mm2, 3
add esi, 16
psrl mm3, 3
paddb mm0, mm1
psrl mm4, 3
movq mm1, mm6
paddb mm2, mm3
paddb mm0, mm4
movq mm3, [esi+edx*4-8]
paddb mm0, mm2
movq mm4, [esi+ebx*4-8]
paddb mm0, [adj2]
pand mm6, mmx_mask3
movq [edi],mm0
pand mm5, mmx_mask3
psrl mm7, 1
pand mm3, mmx_mask3
psrl mm6, 3
pand mm4, mmx_mask3
psrl mm5, 3
paddb mm7, mm6
add edi, 16
psrl mm3, 3
psrl mm4, 3
paddb mm5, mm3
paddb mm7, mm4
dec ecx
paddb mm7, mm5
paddb mm7, [adj2]
movq [edi-8],mm7
jnz mmx_normal_blur_loop
mov of, edi
mov f, esi
};
f2=f+w; // update these bitches
f3=f-w;
}
#endif
x=(w-2)&3;
while (x--)
{
*of++=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]) + adj_tl2;
f++;
f2++;
f3++;
}
// right block
*of++=DIV_4(f[0])+DIV_4(f[-1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++;
}
}
// bottom block
if (at_bottom)
{
unsigned int *f2=f-w;
int adj_tl=0, adj_tl2=0;
if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x03030303; }
int x;
// bottom left
*of++=DIV_2(f[0])+DIV_4(f[1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
// bottom center
x=(w-2)/4;
while (x--)
{
of[0]=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
of[1]=DIV_4(f[1]) + DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + adj_tl2;
of[2]=DIV_4(f[2]) + DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + adj_tl2;
of[3]=DIV_4(f[3]) + DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + adj_tl2;
f+=4;
f2+=4;
of+=4;
}
x=(w-2)&3;
while (x--)
{
*of++=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
f++;
f2++;
}
// bottom right
*of++=DIV_2(f[0])+DIV_4(f[-1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
}
}
#ifndef NO_MMX
__asm emms;
#endif
timingLeave(0);
}
int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (!enabled) return 0;
return max_threads;
}
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 !!enabled;
}
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_Blur(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)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (g_this->enabled==2) CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
else if (g_this->enabled==3) CheckDlgButton(hwndDlg,IDC_RADIO4,BST_CHECKED);
else if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
else CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
if (g_this->roundmode==0) CheckDlgButton(hwndDlg,IDC_ROUNDDOWN,BST_CHECKED);
else CheckDlgButton(hwndDlg,IDC_ROUNDUP,BST_CHECKED);
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_RADIO1)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
g_this->enabled=0;
if (LOWORD(wParam) == IDC_RADIO2)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2))
g_this->enabled=1;
if (LOWORD(wParam) == IDC_RADIO3)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3))
g_this->enabled=2;
if (LOWORD(wParam) == IDC_RADIO4)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO4))
g_this->enabled=3;
if (LOWORD(wParam) == IDC_ROUNDUP)
if (IsDlgButtonChecked(hwndDlg,IDC_ROUNDUP))
g_this->roundmode=1;
if (LOWORD(wParam) == IDC_ROUNDDOWN)
if (IsDlgButtonChecked(hwndDlg,IDC_ROUNDDOWN))
g_this->roundmode=0;
return 0;
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BLUR,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_Blur(char *desc) { return NULL; }
#endif
+285
View File
@@ -0,0 +1,285 @@
/*
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.
*/
#include <windows.h>
#include <stdlib.h>
#include <vfw.h>
#include <commctrl.h>
#include <stdio.h>
#include <math.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#define MOD_NAME "Misc / Custom BPM"
#define C_THISCLASS C_BpmClass
#define SET_BEAT 0x10000000
#define CLR_BEAT 0x20000000
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_CUSTOM_BPM,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
void SliderStep(int Ctl, int *slide);
int enabled;
int arbitrary, skip, invert; // Type of action, adapt = detect beat
int arbVal, skipVal; // Values of arbitrary beat and beat skip
DWORD arbLastTC; // Last tick count used for arbitrary beat
int skipCount; // Beat counter used by beat skipper
int inInc, outInc; // +1/-1, Used by the nifty beatsynced sliders
int inSlide, outSlide; // Positions of sliders
int oldInSlide, oldOutSlide; // Used by timer to detect changes in sliders
int skipfirst;
int count;
};
static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
C_THISCLASS::~C_THISCLASS()
{
}
// configuration read/write
C_THISCLASS::C_THISCLASS() // set up default configuration
{
skipfirst=0;
inSlide=0;
outSlide=0;
oldInSlide=0;
oldOutSlide=0;
enabled = 1;
arbLastTC = GetTickCount();
arbitrary=1;
arbVal = 500;
skipVal = 1;
skipCount = 0;
skip=0;
invert=0;
}
#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) // read configuration of max length "len" from data.
{
int pos=0;
if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { arbitrary=GET_INT(); pos+=4; }
if (len-pos >= 4) { skip=GET_INT(); pos+=4; }
if (len-pos >= 4) { invert=GET_INT(); pos+=4; }
if (len-pos >= 4) { arbVal=GET_INT(); pos+=4; }
if (len-pos >= 4) { skipVal=GET_INT(); pos+=4; }
if (len-pos >= 4) { skipfirst=GET_INT(); pos+=4; }
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(arbitrary); pos+=4;
PUT_INT(skip); pos+=4;
PUT_INT(invert); pos+=4;
PUT_INT(arbVal); pos+=4;
PUT_INT(skipVal); pos+=4;
PUT_INT(skipfirst); pos+=4;
return pos;
}
void C_THISCLASS::SliderStep(int Ctl, int *slide)
{
*slide += Ctl == IDC_IN ? inInc : outInc;
if (!*slide || *slide == 8) (Ctl == IDC_IN ? inInc : outInc) *= -1;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (!enabled) return 0;
if (isBeat&0x80000000) return 0;
if (isBeat) // Show the beat received from AVS
{
SliderStep(IDC_IN, &inSlide);
count++;
}
if (skipfirst != 0 && count <= skipfirst)
return isBeat ? CLR_BEAT : 0;
if (arbitrary)
{
DWORD TCNow = GetTickCount();
if (TCNow > arbLastTC + arbVal)
{
arbLastTC = TCNow;
SliderStep(IDC_OUT, &outSlide);
return SET_BEAT;
}
return CLR_BEAT;
}
if (skip)
{
if (isBeat && ++skipCount >= skipVal+1)
{
skipCount = 0;
SliderStep(IDC_OUT, &outSlide);
return SET_BEAT;
}
return CLR_BEAT;
}
if (invert)
{
if (isBeat)
return CLR_BEAT;
else
{
SliderStep(IDC_OUT, &outSlide);
return SET_BEAT;
}
}
return 0;
}
// configuration dialog stuff
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
char txt[40], beat[16], beats[16];
g_ConfigThis->inInc = 1;
g_ConfigThis->outInc = 1;
g_ConfigThis->inSlide = 0;
g_ConfigThis->outSlide = 0;
if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_ConfigThis->arbitrary) CheckDlgButton(hwndDlg,IDC_ARBITRARY,BST_CHECKED);
if (g_ConfigThis->skip) CheckDlgButton(hwndDlg,IDC_SKIP,BST_CHECKED);
if (g_ConfigThis->invert) CheckDlgButton(hwndDlg,IDC_INVERT,BST_CHECKED);
SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETTICFREQ, 100, 0);
SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETRANGE, TRUE, MAKELONG(200, 10000));
SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETRANGE, TRUE, MAKELONG(1, 16));
SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETPOS, TRUE, g_ConfigThis->arbVal);
SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETPOS, TRUE, g_ConfigThis->skipVal);
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETTICFREQ, 1, 0);
SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETPOS, TRUE, g_ConfigThis->skipfirst);
wsprintf(txt, "%d bpm", 60000 / g_ConfigThis->arbVal);
SetDlgItemText(hwndDlg, IDC_ARBTXT, txt);
WASABI_API_LNGSTRING_BUF(IDS_BEAT,beat,16);
WASABI_API_LNGSTRING_BUF(IDS_BEATS,beats,16);
wsprintf(txt, "%d %s", g_ConfigThis->skipVal, g_ConfigThis->skipVal > 1 ? beats : beat);
SetDlgItemText(hwndDlg, IDC_SKIPTXT, txt);
wsprintf(txt, "%d %s", g_ConfigThis->skipfirst, g_ConfigThis->skipfirst > 1 ? beats : beat);
SetDlgItemText(hwndDlg, IDC_SKIPFIRSTTXT, txt);
SetTimer(hwndDlg, 0, 50, NULL);
}
return 1;
case WM_TIMER:
{
if (g_ConfigThis->oldInSlide != g_ConfigThis->inSlide) {
SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETPOS, TRUE, g_ConfigThis->inSlide); g_ConfigThis->oldInSlide=g_ConfigThis->inSlide; }
if (g_ConfigThis->oldOutSlide != g_ConfigThis->outSlide) {
SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETPOS, TRUE, g_ConfigThis->outSlide); g_ConfigThis->oldOutSlide=g_ConfigThis->outSlide; }
}
return 0;
case WM_NOTIFY:
{
char txt[40], beat[16], beats[16];
if (LOWORD(wParam) == IDC_ARBVAL)
g_ConfigThis->arbVal = SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_GETPOS, 0, 0);
if (LOWORD(wParam) == IDC_SKIPVAL)
g_ConfigThis->skipVal = SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_GETPOS, 0, 0);
if (LOWORD(wParam) == IDC_SKIPFIRST)
g_ConfigThis->skipfirst = SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_GETPOS, 0, 0);
wsprintf(txt, "%d bpm", 60000 / g_ConfigThis->arbVal);
SetDlgItemText(hwndDlg, IDC_ARBTXT, txt);
WASABI_API_LNGSTRING_BUF(IDS_BEAT,beat,16);
WASABI_API_LNGSTRING_BUF(IDS_BEATS,beats,16);
wsprintf(txt, "%d %s", g_ConfigThis->skipVal, g_ConfigThis->skipVal > 1 ? beats : beat);
SetDlgItemText(hwndDlg, IDC_SKIPTXT, txt);
wsprintf(txt, "%d %s", g_ConfigThis->skipfirst, g_ConfigThis->skipfirst > 1 ? beats : beat);
SetDlgItemText(hwndDlg, IDC_SKIPFIRSTTXT, txt);
return 0;
}
case WM_COMMAND:
if ((LOWORD(wParam) == IDC_CHECK1) ||
(LOWORD(wParam) == IDC_ARBITRARY) ||
(LOWORD(wParam) == IDC_SKIP) ||
(LOWORD(wParam) == IDC_INVERT))
{
g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
g_ConfigThis->arbitrary=IsDlgButtonChecked(hwndDlg,IDC_ARBITRARY)?1:0;
g_ConfigThis->skip=IsDlgButtonChecked(hwndDlg,IDC_SKIP)?1:0;
g_ConfigThis->invert=IsDlgButtonChecked(hwndDlg,IDC_INVERT)?1:0;
}
return 0;
case WM_DESTROY:
KillTimer(hwndDlg, 0);
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BPM,hwndParent,g_DlgProc);
}
C_RBASE *R_Bpm(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
@@ -0,0 +1,506 @@
/*
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.
*/
#include <windows.h>
#include <stdlib.h>
#include <vfw.h>
#include <commctrl.h>
#include <math.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define MOD_NAME "Trans / Brightness"
#define C_THISCLASS C_BrightnessClass
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BRIGHTNESS,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
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
int enabled;
int redp, greenp, bluep;
int blend, blendavg;
int dissoc;
int color;
int exclude;
int distance;
int tabs_needinit;
int green_tab[256];
int red_tab[256];
int blue_tab[256];
};
static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
C_THISCLASS::~C_THISCLASS()
{
}
// configuration read/write
C_THISCLASS::C_THISCLASS() // set up default configuration
{
tabs_needinit=1;
redp=0;
bluep=0;
greenp=0;
blend=0;
blendavg=1;
enabled=1;
color=0;
exclude=0;
distance = 16;
dissoc=0;
}
#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) // read configuration of max length "len" from data.
{
int pos=0;
if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
if (len-pos >= 4) { redp=GET_INT(); pos+=4; }
if (len-pos >= 4) { greenp=GET_INT(); pos+=4; }
if (len-pos >= 4) { bluep=GET_INT(); pos+=4; }
if (len-pos >= 4) { dissoc=GET_INT(); pos+=4; }
if (len-pos >= 4) { color=GET_INT(); pos+=4; }
if (len-pos >= 4) { exclude=GET_INT(); pos+=4; }
if (len-pos >= 4) { distance=GET_INT(); pos+=4; }
tabs_needinit=1;
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(blendavg); pos+=4;
PUT_INT(redp); pos+=4;
PUT_INT(greenp); pos+=4;
PUT_INT(bluep); pos+=4;
PUT_INT(dissoc); pos+=4;
PUT_INT(color); pos+=4;
PUT_INT(exclude); pos+=4;
PUT_INT(distance); pos+=4;
return pos;
}
static __inline int iabs(int v)
{
return (v<0) ? -v : v;
}
static __inline int inRange(int color, int ref, int distance)
{
if (iabs((color & 0xFF) - (ref & 0xFF)) > distance) return 0;
if (iabs(((color) & 0xFF00) - ((ref) & 0xFF00)) > (distance<<8)) return 0;
if (iabs(((color) & 0xFF0000) - ((ref) & 0xFF0000)) > (distance<<16)) return 0;
return 1;
}
static void mmx_brighten_block(int *p, int rm, int gm, int bm, int l)
{
int poo[2]=
{
(bm>>8)|((gm>>8)<<16),
rm>>8
};
__asm
{
mov eax, p
mov ecx, l
movq mm1, [poo]
align 16
mmx_brightblock_loop:
pxor mm0, mm0
punpcklbw mm0, [eax]
pmulhw mm0, mm1
packuswb mm0, mm0
movd [eax], mm0
add eax, 4
dec ecx
jnz mmx_brightblock_loop
emms
};
}
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);
}
int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int rm=(int)((1+(redp < 0 ? 1 : 16)*((float)redp/4096))*65536.0);
int gm=(int)((1+(greenp < 0 ? 1 : 16)*((float)greenp/4096))*65536.0);
int bm=(int)((1+(bluep < 0 ? 1 : 16)*((float)bluep/4096))*65536.0);
if (!enabled) return 0;
if (tabs_needinit)
{
int n;
for (n = 0; n < 256; n ++)
{
red_tab[n] = (n*rm)&0xffff0000;
if (red_tab[n]>0xff0000) red_tab[n]=0xff0000;
if (red_tab[n]<0) red_tab[n]=0;
green_tab[n] = ((n*gm)>>8)&0xffff00;
if (green_tab[n]>0xff00) green_tab[n]=0xff00;
if (green_tab[n]<0) green_tab[n]=0;
blue_tab[n] = ((n*bm)>>16)&0xffff;
if (blue_tab[n]>0xff) blue_tab[n]=0xff;
if (blue_tab[n]<0) blue_tab[n]=0;
}
tabs_needinit=0;
}
if (isBeat&0x80000000) return 0;
return max_threads;
}
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 0;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
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 (!enabled || (isBeat&0x80000000)) return;
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 l=w*outh;
int *p = framebuffer + start_l * w;
if (blend)
{
if (!exclude)
{
while (l--)
{
int pix=*p;
*p++ = BLEND(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
}
}
else
{
while (l--)
{
int pix=*p;
if (!inRange(pix,color,distance))
{
*p = BLEND(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
}
p++;
}
}
}
else if (blendavg)
{
if (!exclude)
{
while (l--)
{
int pix=*p;
*p++ = BLEND_AVG(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
}
}
else
{
while (l--)
{
int pix=*p;
if (!inRange(pix,color,distance))
{
*p = BLEND_AVG(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
}
p++;
}
}
}
else
{
if (!exclude)
{
#if 1 // def NO_MMX
while (l--)
{
int pix=*p;
*p++ = red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff];
}
#else
mmx_brighten_block(p,rm,gm,bm,l);
#endif
}
else
{
while (l--)
{
int pix=*p;
if (!inRange(pix,color,distance))
{
*p = red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff];
}
p++;
}
}
}
}
// configuration dialog stuff
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETRANGEMIN, TRUE, 0);
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETRANGEMIN, TRUE, 0);
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETRANGEMIN, TRUE, 0);
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETRANGEMAX, TRUE, 8192);
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETRANGEMAX, TRUE, 8192);
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETRANGEMAX, TRUE, 8192);
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETTICFREQ, 256, 0);
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETTICFREQ, 256, 0);
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETTICFREQ, 256, 0);
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETPOS, TRUE, g_ConfigThis->distance);
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETTICFREQ, 16, 0);
if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_ConfigThis->exclude) CheckDlgButton(hwndDlg,IDC_EXCLUDE,BST_CHECKED);
if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
if (g_ConfigThis->dissoc) CheckDlgButton(hwndDlg,IDC_DISSOC,BST_CHECKED);
if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
return 1;
case WM_NOTIFY:
{
if (LOWORD(wParam) == IDC_DISTANCE)
{
g_ConfigThis->distance = SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_GETPOS, 0, 0);
}
if (LOWORD(wParam) == IDC_RED)
{
g_ConfigThis->redp = SendDlgItemMessage(hwndDlg, IDC_RED, TBM_GETPOS, 0, 0)-4096;
rred:
g_ConfigThis->tabs_needinit=1;
if (!g_ConfigThis->dissoc)
{
g_ConfigThis->greenp = g_ConfigThis->redp;
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
g_ConfigThis->bluep = g_ConfigThis->redp;
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
}
}
if (LOWORD(wParam) == IDC_GREEN)
{
g_ConfigThis->greenp = SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_GETPOS, 0, 0)-4096;
rgreen:
g_ConfigThis->tabs_needinit=1;
if (!g_ConfigThis->dissoc)
{
g_ConfigThis->redp = g_ConfigThis->greenp;
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
g_ConfigThis->bluep = g_ConfigThis->greenp;
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
}
}
if (LOWORD(wParam) == IDC_BLUE)
{
g_ConfigThis->bluep = SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_GETPOS, 0, 0)-4096;
rblue:
g_ConfigThis->tabs_needinit=1;
if (!g_ConfigThis->dissoc)
{
g_ConfigThis->redp = g_ConfigThis->bluep;
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
g_ConfigThis->greenp = g_ConfigThis->bluep;
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
}
}
return 0;
}
case WM_COMMAND:
if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
{
int *a=&(g_ConfigThis->color);
static COLORREF custcolors[16];
CHOOSECOLOR cs;
cs.lStructSize = sizeof(cs);
cs.hwndOwner = hwndDlg;
cs.hInstance = 0;
cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
cs.lpCustColors = custcolors;
cs.Flags = CC_RGBINIT|CC_FULLOPEN;
if (ChooseColor(&cs))
{
*a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
g_ConfigThis->color = *a;
}
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
if (LOWORD(wParam) == IDC_BRED)
{
g_ConfigThis->redp = 0;
SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
goto rred; // gotos are so sweet ;)
}
if (LOWORD(wParam) == IDC_BGREEN)
{
g_ConfigThis->greenp = 0;
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
goto rgreen;
}
if (LOWORD(wParam) == IDC_BBLUE)
{
g_ConfigThis->bluep = 0;
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
goto rblue;
}
if ((LOWORD(wParam) == IDC_CHECK1) ||
(LOWORD(wParam) == IDC_ADDITIVE) ||
(LOWORD(wParam) == IDC_REPLACE) ||
(LOWORD(wParam) == IDC_EXCLUDE) ||
(LOWORD(wParam) == IDC_DISSOC) ||
(LOWORD(wParam) == IDC_5050) )
{
g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
g_ConfigThis->exclude=IsDlgButtonChecked(hwndDlg,IDC_EXCLUDE)?1:0;
g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
g_ConfigThis->dissoc=IsDlgButtonChecked(hwndDlg,IDC_DISSOC)?1:0;
if (!g_ConfigThis->dissoc)
{
g_ConfigThis->greenp = g_ConfigThis->redp;
SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
g_ConfigThis->bluep = g_ConfigThis->redp;
SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
}
}
return 0;
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL) // paint nifty color button
{
int w=di->rcItem.right-di->rcItem.left;
int _color=g_ConfigThis->color;
_color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
HPEN hPen,hOldPen;
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
hBrush = CreateBrushIndirect(&lb);
hOldPen=(HPEN)SelectObject(di->hDC,hPen);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
SelectObject(di->hDC,hOldPen);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
DeleteObject(hPen);
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BRIGHTNESS,hwndParent,g_DlgProc);
}
// export stuff
C_RBASE *R_Brightness(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
#else
C_RBASE *R_Brightness(char *desc) { return NULL; }
#endif
@@ -0,0 +1,315 @@
/*
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 (sets alpha to 0 on rendered portions) 11/21/99
#include <windows.h>
#include <math.h>
#include "r_defs.h"
#include "resource.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_BSpinClass
#define MOD_NAME "Render / Bass Spin"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_BASS_SPIN,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
void my_triangle(int *fb, int points[6], int width, int height, int color);
int enabled;
int colors[2];
int mode;
int last_a;
int lx[2][2],ly[2][2];
double r_v[2];
double v[2];
double dir[2];
};
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { colors[0]=GET_INT(); pos+=4; }
if (len-pos >= 4) { colors[1]=GET_INT(); pos+=4; }
if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(colors[0]); pos+=4;
PUT_INT(colors[1]); pos+=4;
PUT_INT(mode); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
last_a=0;
enabled=3;
colors[0]=RGB(255,255,255);
colors[1]=RGB(255,255,255);
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
memset(v,0,sizeof(v));
r_v[0]=3.14159;
r_v[1]=0.0;
dir[0]=-1.0;
dir[1]=1.0;
mode=1;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int y,x;
if (isBeat&0x80000000) return 0;
for (y = 0; y < 2; y ++)
{
if (!(enabled&(1<<y))) continue;
unsigned char *fa_data=(unsigned char *)visdata[0][y];
int xp,yp;
int ss=min(h/2,(w*3)/8);
double s=(double)ss;
int c_x = (!y?w/2-ss/2:w/2+ss/2);
int a=0,d=0;
int nc=1;
int oc6 = colors[y];
for (x = 0; x < 44; x ++)
{
d+=fa_data[x];
}
a=(d*512)/(last_a+30*256);
last_a=d;
if (a > 255) a =255;
v[y] = 0.7*(max(a-104,12)/96.0) + 0.3*v[y];
r_v[y] += 3.14159/6.0 * v[y] * dir[y];
s *= a*1.0/256.0f;
yp=(int)(sin(r_v[y])*s);
xp=(int)(cos(r_v[y])*s);
if (mode==0)
{
if (lx[0][y] || ly[0][y]) line(framebuffer,lx[0][y],ly[0][y],xp+c_x,yp+h/2,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
lx[0][y]=xp+c_x;
ly[0][y]=yp+h/2;
line(framebuffer,c_x,h/2,c_x+xp,h/2+yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
if (lx[1][y] || ly[1][y]) line(framebuffer,lx[1][y],ly[1][y],c_x-xp,h/2-yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
lx[1][y]=c_x-xp;
ly[1][y]=h/2-yp;
line(framebuffer,c_x,h/2,c_x-xp,h/2-yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
}
else if (mode==1)
{
if (lx[0][y] || ly[0][y])
{
int points[6] = { c_x,h/2, lx[0][y], ly[0][y], xp+c_x,yp+h/2 };
my_triangle(framebuffer,points,w,h,oc6);
}
lx[0][y]=xp+c_x;
ly[0][y]=yp+h/2;
if (lx[1][y] || ly[1][y])
{
int points[6] = { c_x,h/2, lx[1][y], ly[1][y], c_x-xp,h/2-yp };
my_triangle(framebuffer,points,w,h,oc6);
}
lx[1][y]=c_x-xp;
ly[1][y]=h/2-yp;
}
}
return 0;
}
C_RBASE *R_BSpin(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
switch (di->CtlID)
{
case IDC_LC:
GR_DrawColoredButton(di,g_this->colors[0]);
break;
case IDC_RC:
GR_DrawColoredButton(di,g_this->colors[1]);
break;
}
}
return 0;
case WM_INITDIALOG:
if (g_this->enabled&1) CheckDlgButton(hwndDlg,IDC_LEFT,BST_CHECKED);
if (g_this->enabled&2) CheckDlgButton(hwndDlg,IDC_RIGHT,BST_CHECKED);
if (g_this->mode==0) CheckDlgButton(hwndDlg,IDC_LINES,BST_CHECKED);
if (g_this->mode==1) CheckDlgButton(hwndDlg,IDC_TRI,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_LINES:
g_this->mode=IsDlgButtonChecked(hwndDlg,IDC_LINES)?0:1;
return 0;
case IDC_TRI:
g_this->mode=IsDlgButtonChecked(hwndDlg,IDC_TRI)?1:0;
return 0;
case IDC_LEFT:
g_this->enabled&=~1;
g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_LEFT)?1:0;
return 0;
case IDC_RIGHT:
g_this->enabled&=~2;
g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_RIGHT)?2:0;
return 0;
case IDC_LC:
if (!a) a=&g_this->colors[0];
case IDC_RC:
if (!a) a=&g_this->colors[1];
GR_SelectColor(hwndDlg,a);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
return 0;
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BSPIN,hwndParent,g_DlgProc);
}
#define F16(x) ((x)<<16)
void C_THISCLASS::my_triangle(int *fb, int points[6], int width, int height, int color)
{
int ymax;
int p;
int y;
int dx1,dx2;
int x1,x2;
for (y = 0; y < 2; y ++)
{
if (points[1] > points[3])
{
p=points[2]; points[2]=points[0]; points[0]=p;
p=points[3]; points[3]=points[1]; points[1]=p;
}
if (points[3] > points[5])
{
p=points[4]; points[4]=points[2]; points[2]=p;
p=points[5]; points[5]=points[3]; points[3]=p;
}
}
x1=x2=F16(points[0]);
if (points[1] < points[3])
{
dx1 = F16(points[2]-points[0])/(points[3]-points[1]);
} else dx1=0;
if (points[1] < points[5])
dx2 = F16(points[4]-points[0])/(points[5]-points[1]);
else dx2=0;
fb += points[1]*width;
ymax = min(points[5],height);
for (y = points[1]; y < ymax; y ++)
{
if (y == points[3])
{
if (y == points[5]) return;
x1=F16(points[2]);
dx1=F16(points[4]-points[2])/(points[5]-points[3]);
}
if (y >= 0) {
int x,xl;
x=(min(x1,x2)-32768)>>16;
xl=((max(x1,x2)+32768)>>16)-x;
if (xl < 0) xl=-xl;
if (!xl) xl++;
{
int *t=fb+x;
if (x < 0) { t-=x; xl-=x; }
if (x+xl >= width) xl=width-x;
if (xl>0) while (xl--) BLEND_LINE(t++,color);
}
}
fb += width;
x1+=dx1;
x2+=dx2;
}
}
#else
C_RBASE *R_BSpin(char *desc) { return NULL; }
#endif
@@ -0,0 +1,562 @@
/*
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.
*/
#include <windows.h>
#include <stdlib.h>
#include <vfw.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#include "r_defs.h"
#include "r_stack.h"
#include "avs_eelif.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define MOD_NAME "Trans / Bump"
#define C_THISCLASS C_BumpClass
class C_THISCLASS : public C_RBASE {
protected:
public:
C_THISCLASS();
float GET_FLOAT(unsigned char *data, int pos);
void PUT_FLOAT(float f, unsigned char *data, int pos);
void InitializeStars(int Start);
void CreateStar(int A);
virtual ~C_THISCLASS();
virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BUMP,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int __inline depthof(int c, int i);
int enabled;
int depth;
int depth2;
int onbeat;
int durFrames;
int thisDepth;
int blend;
int blendavg;
int nF;
NSEEL_CODEHANDLE codeHandle;
NSEEL_CODEHANDLE codeHandleBeat;
NSEEL_CODEHANDLE codeHandleInit;
double *var_x;
double *var_y;
double *var_isBeat;
double *var_isLongBeat;
double *var_bi;
RString code1,code2,code3;
int need_recompile;
int showlight;
int initted;
int invert;
NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
int oldstyle;
int buffern;
CRITICAL_SECTION rcs;
};
static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
C_THISCLASS::~C_THISCLASS()
{
freeCode(codeHandle);
freeCode(codeHandleBeat);
freeCode(codeHandleInit);
DeleteCriticalSection(&rcs);
AVS_EEL_QUITINST();
}
// configuration read/write
C_THISCLASS::C_THISCLASS() // set up default configuration
{
AVS_EEL_INITINST();
InitializeCriticalSection(&rcs);
buffern=0;
oldstyle=0;
invert=0;
enabled=1;
onbeat = 0;
durFrames = 15;
depth=30;
depth2=100;
nF=0;
showlight=0;
thisDepth=depth;
blend = 0;
blendavg = 0;
code1.assign("x=0.5+cos(t)*0.3;\r\ny=0.5+sin(t)*0.3;\r\nt=t+0.1;");
code2.assign("");
code3.assign("t=0;");
codeHandle=0;
codeHandleBeat=0;
codeHandleInit=0;
var_bi=0;
initted=0;
need_recompile=1;
}
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
if (len-pos >= 4) { durFrames=GET_INT(); pos+=4; }
if (len-pos >= 4) { depth=GET_INT(); pos+=4; }
if (len-pos >= 4) { depth2=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
load_string(code1,data,pos,len);
load_string(code2,data,pos,len);
load_string(code3,data,pos,len);
if (len-pos >= 4) { showlight=GET_INT(); pos+=4; }
if (len-pos >= 4) { invert=GET_INT(); pos+=4; }
if (len-pos >= 4) { oldstyle=GET_INT(); pos+=4; } else oldstyle=1;
if (len-pos >= 4) { buffern=GET_INT(); pos+=4; }
thisDepth=depth;
nF=0;
need_recompile=1;
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(onbeat); pos+=4;
PUT_INT(durFrames); pos+=4;
PUT_INT(depth); pos+=4;
PUT_INT(depth2); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(blendavg); pos+=4;
save_string(data, pos, code1);
save_string(data, pos, code2);
save_string(data, pos, code3);
PUT_INT(showlight); pos+=4;
PUT_INT(invert); pos+=4;
PUT_INT(oldstyle); pos+=4;
PUT_INT(buffern); pos+=4;
return pos;
}
int __inline C_THISCLASS::depthof(int c, int i)
{
int r= max(max((c & 0xFF), ((c & 0xFF00)>>8)), (c & 0xFF0000)>>16);
return i ? 255 - r : r;
}
static int __inline setdepth(int l, int c)
{
int r;
r=min((c&0xFF)+l, 254);
r|=min(((c&0xFF00))+(l<<8),254<<8);
r|=min(((c&0xFF0000))+(l<<16),254<<16);
return r;
}
static int __inline setdepth0(int c)
{
int r;
r=min((c&0xFF), 254);
r|=min(((c&0xFF00)),254<<8);
r|=min(((c&0xFF0000)),254<<16);
return r;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
#define abs(x) (( x ) >= 0 ? ( x ) : - ( x ))
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int cx,cy;
int curbuf;
if (!enabled) return 0;
if (need_recompile)
{
EnterCriticalSection(&rcs);
if (!var_bi || g_reset_vars_on_recompile)
{
clearVars();
var_x = registerVar("x");
var_y = registerVar("y");
var_isBeat = registerVar("isbeat");
var_isLongBeat = registerVar("islbeat");
var_bi = registerVar("bi");
*var_bi = 1.0;
initted=0;
}
need_recompile=0;
freeCode(codeHandle);
freeCode(codeHandleBeat);
freeCode(codeHandleInit);
codeHandle = compileCode(code1.get());
codeHandleBeat = compileCode(code2.get());
codeHandleInit = compileCode(code3.get());
LeaveCriticalSection(&rcs);
}
if (isBeat&0x80000000) return 0;
int *depthbuffer = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
if (!depthbuffer) return 0;
curbuf = (depthbuffer==framebuffer);
if (!initted)
{
executeCode(codeHandleInit,visdata);
initted=1;
}
executeCode(codeHandle,visdata);
if (isBeat) executeCode(codeHandleBeat,visdata);
if (isBeat)
*var_isBeat=-1;
else
*var_isBeat=1;
if (nF)
*var_isLongBeat=-1;
else
*var_isLongBeat=1;
if (onbeat && isBeat)
{
thisDepth=depth2;
nF = durFrames;
}
else if (!nF) thisDepth = depth;
memset(fbout, 0, w*h*4); // previous effects may have left fbout in a mess
if (oldstyle)
{
cx = (int)(*var_x/100.0*w);
cy = (int)(*var_y/100.0*h);
}
else
{
cx = (int)(*var_x*w);
cy = (int)(*var_y*h);
}
cx = max(0, min(w, cx));
cy = max(0, min(h, cy));
if (showlight) fbout[cx+cy*w]=0xFFFFFF;
if (var_bi)
{
*var_bi = min(max(*var_bi, 0), 1);
thisDepth = (int)(thisDepth * *var_bi);
}
int thisDepth_scaled=(thisDepth<<8)/100;
depthbuffer += w+1;
framebuffer += w+1;
fbout += w+1;
int ly=1-cy;
int i=h-2;
while (i--)
{
int j=w-2;
int lx=1-cx;
if (blend)
{
while (j--)
{
int m1,p1,mw,pw;
m1=depthbuffer[-1];
p1=depthbuffer[1];
mw=depthbuffer[-w];
pw=depthbuffer[w];
if (!curbuf || (curbuf && (m1||p1||mw||pw)))
{
int coul1,coul2;
coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
coul1=127-abs(coul1);
coul2=127-abs(coul2);
if (coul1<=0||coul2<=0)
coul1=setdepth0(framebuffer[0]);
else
coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
fbout[0]=BLEND(framebuffer[0], coul1);
}
depthbuffer++;
framebuffer++;
fbout++;
lx++;
}
}
else if (blendavg)
{
while (j--)
{
int m1,p1,mw,pw;
m1=depthbuffer[-1];
p1=depthbuffer[1];
mw=depthbuffer[-w];
pw=depthbuffer[w];
if (!curbuf || (curbuf && (m1||p1||mw||pw)))
{
int coul1,coul2;
coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
coul1=127-abs(coul1);
coul2=127-abs(coul2);
if (coul1<=0||coul2<=0)
coul1=setdepth0(framebuffer[0]);
else
coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
fbout[0]=BLEND_AVG(framebuffer[0], coul1);
}
depthbuffer++;
framebuffer++;
fbout++;
lx++;
}
}
else
{
while (j--)
{
int m1,p1,mw,pw;
m1=depthbuffer[-1];
p1=depthbuffer[1];
mw=depthbuffer[-w];
pw=depthbuffer[w];
if (!curbuf || (curbuf && (m1||p1||mw||pw)))
{
int coul1,coul2;
coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
coul1=127-abs(coul1);
coul2=127-abs(coul2);
if (coul1<=0||coul2<=0)
coul1=setdepth0(framebuffer[0]);
else
coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
fbout[0]=coul1;
}
depthbuffer++;
framebuffer++;
fbout++;
lx++;
}
}
depthbuffer+=2;
framebuffer+=2;
fbout+=2;
ly++;
}
if (nF)
{
nF--;
if (nF)
{
int a = abs(depth - depth2) / durFrames;
thisDepth += a * (depth2 > depth ? -1 : 1);
}
}
return 1;
}
// configuration dialog stuff
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SetDlgItemText(hwndDlg, IDC_CODE1, g_ConfigThis->code1.get());
SetDlgItemText(hwndDlg, IDC_CODE2, g_ConfigThis->code2.get());
SetDlgItemText(hwndDlg, IDC_CODE3, g_ConfigThis->code3.get());
SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETTICFREQ, 10, 0);
SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETPOS, TRUE, g_ConfigThis->depth);
SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETTICFREQ, 10, 0);
SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETPOS, TRUE, g_ConfigThis->depth2);
SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETTICFREQ, 10, 0);
SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETPOS, TRUE, g_ConfigThis->durFrames);
if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_ConfigThis->invert) CheckDlgButton(hwndDlg,IDC_INVERTDEPTH,BST_CHECKED);
if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_ONBEAT,BST_CHECKED);
if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
if (g_ConfigThis->showlight) CheckDlgButton(hwndDlg,IDC_DOT,BST_CHECKED);
if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_CURRENT));
{
int i=0;
char txt[64];
for (i=0;i<NBUF;i++)
{
wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)txt);
}
}
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, (WPARAM) g_ConfigThis->buffern, 0);
return 1;
case WM_NOTIFY:
{
if (LOWORD(wParam) == IDC_DEPTH)
g_ConfigThis->depth = SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_GETPOS, 0, 0);
if (LOWORD(wParam) == IDC_DEPTH2)
g_ConfigThis->depth2 = SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_GETPOS, 0, 0);
if (LOWORD(wParam) == IDC_BEATDUR)
g_ConfigThis->durFrames = SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_GETPOS, 0, 0);
}
return 0;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_HELPBTN)
{
/* char text[4096];
WASABI_API_LNGSTRING_BUF(IDS_BUMP_LIGHT_POSITION,text,4096);
int titlelen = lstrlen(text)+1;
lstrcpyn(text+titlelen,GetTextResource(IDR_BUMP_LIGHT_POSITION),4095-titlelen);
*/
char *text="Bump Light Position\0"
"How to use the custom light position evaluator:\r\n"
" * Init code will be executed each time the window size is changed\r\n"
" or when the effect loads\r\n"
" * Frame code is executed before rendering a new frame\r\n"
" * Beat code is executed when a beat is detected\r\n"
"\r\n"
"Predefined variables:\r\n"
" x : Light x position, ranges from 0 (left) to 1 (right) (0.5 = center)\r\n"
" y : Light y position, ranges from 0 (top) to 1 (bottom) (0.5 = center)\r\n"
" isBeat : 1 if no beat, -1 if beat (weird, but old)\r\n"
" isLBeat: same as isBeat but persists according to 'shorter/longer' settings\r\n"
" (usable only with OnBeat checked)\r\n"
" bi: Bump intensity, ranges from 0 (flat) to 1 (max specified bump, default)\r\n"
" You may also use temporary variables accross code segments\r\n"
"\r\n"
"Some examples:\r\n"
" Circular move\r\n"
" Init : t=0\r\n"
" Frame: x=0.5+cos(t)*0.3; y=0.5+sin(t)*0.3; t=t+0.1;\r\n"
" Nice motion:\r\n"
" Init : t=0;u=0\r\n"
" Frame: x=0.5+cos(t)*0.3; y=0.5+cos(u)*0.3; t=t+0.1; u=u+0.012;\r\n"
;
compilerfunctionlist(hwndDlg,text);
return 0;
}
if ((LOWORD(wParam) == IDC_CHECK1) ||
(LOWORD(wParam) == IDC_ONBEAT) ||
(LOWORD(wParam) == IDC_ADDITIVE) ||
(LOWORD(wParam) == IDC_REPLACE) ||
(LOWORD(wParam) == IDC_DOT) ||
(LOWORD(wParam) == IDC_INVERTDEPTH) ||
(LOWORD(wParam) == IDC_5050) )
{
g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
g_ConfigThis->showlight=IsDlgButtonChecked(hwndDlg,IDC_DOT)?1:0;
g_ConfigThis->invert=IsDlgButtonChecked(hwndDlg,IDC_INVERTDEPTH)?1:0;
}
if (LOWORD(wParam) == IDC_CODE1 && HIWORD(wParam) == EN_CHANGE)
{
EnterCriticalSection(&g_ConfigThis->rcs);
g_ConfigThis->code1.get_from_dlgitem(hwndDlg,IDC_CODE1);
g_ConfigThis->need_recompile=1;
LeaveCriticalSection(&g_ConfigThis->rcs);
}
if (LOWORD(wParam) == IDC_CODE2 && HIWORD(wParam) == EN_CHANGE)
{
EnterCriticalSection(&g_ConfigThis->rcs);
g_ConfigThis->code2.get_from_dlgitem(hwndDlg,IDC_CODE2);
g_ConfigThis->need_recompile=1;
LeaveCriticalSection(&g_ConfigThis->rcs);
}
if (LOWORD(wParam) == IDC_CODE3 && HIWORD(wParam) == EN_CHANGE)
{
EnterCriticalSection(&g_ConfigThis->rcs);
g_ConfigThis->code3.get_from_dlgitem(hwndDlg,IDC_CODE3);
g_ConfigThis->need_recompile=1;
g_ConfigThis->initted=0;
LeaveCriticalSection(&g_ConfigThis->rcs);
}
if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO1) // handle clicks to combo box
g_ConfigThis->buffern = SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0);
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_BUMP,hwndParent,g_DlgProc);
}
// export stuff
C_RBASE *R_Bump(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
#else
C_RBASE *R_Bump(char *desc) { return NULL; }
#endif
@@ -0,0 +1,362 @@
/*
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.
*/
#include <windows.h>
#include <commctrl.h>
#include <time.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
// this will be the directory and APE name displayed in the AVS Editor
#define MOD_NAME "Trans / Channel Shift"
#define C_THISCLASS C_ChannelShiftClass
typedef struct {
int mode;
int onbeat;
} apeconfig;
class C_THISCLASS : public C_RBASE
{
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 HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual char *get_desc();
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
apeconfig config;
HWND hwndDlg;
};
// global configuration dialog pointer
static C_THISCLASS *g_ConfigThis;
static HINSTANCE g_hDllInstance;
// this is where we deal with the configuration screen
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int ids[] = { IDC_RBG, IDC_BRG, IDC_BGR, IDC_GBR, IDC_GRB, IDC_RGB };
switch (uMsg)
{
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
for (int i=0;i<sizeof(ids)/sizeof(ids[0]);i++)
if (IsDlgButtonChecked(hwndDlg, ids[i]))
g_ConfigThis->config.mode = ids[i];
g_ConfigThis->config.onbeat = IsDlgButtonChecked(hwndDlg, IDC_ONBEAT) ? 1 : 0;
}
return 1;
case WM_INITDIALOG:
g_ConfigThis->hwndDlg = hwndDlg;
CheckDlgButton(hwndDlg, g_ConfigThis->config.mode, 1);
if (g_ConfigThis->config.onbeat)
CheckDlgButton(hwndDlg, IDC_ONBEAT, 1);
return 1;
case WM_DESTROY:
KillTimer(hwndDlg, 1);
return 1;
}
return 0;
}
// set up default configuration
C_THISCLASS::C_THISCLASS()
{
memset(&config, 0, sizeof(apeconfig));
config.mode = IDC_RBG;
config.onbeat = 1;
}
// virtual destructor
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (isBeat&0x80000000) return 0;
int c;
int modes[] = { IDC_RGB, IDC_RBG, IDC_GBR, IDC_GRB, IDC_BRG, IDC_BGR };
if (isBeat && config.onbeat) {
config.mode = modes[rand() % 6];
}
c = w*h;
switch (config.mode) {
default:
case IDC_RGB:
return 0;
case IDC_RBG:
__asm {
mov ebx, framebuffer;
mov ecx, c;
lp1:
sub ecx, 4;
mov eax, dword ptr [ebx+ecx*4];
xchg ah, al;
mov [ebx+ecx*4], eax;
mov eax, dword ptr [ebx+ecx*4+4];
xchg ah, al;
mov [ebx+ecx*4+4], eax;
mov eax, dword ptr [ebx+ecx*4+8];
xchg ah, al;
mov [ebx+ecx*4+8], eax;
mov eax, dword ptr [ebx+ecx*4+12];
xchg ah, al;
mov [ebx+ecx*4+12], eax;
test ecx, ecx;
jnz lp1;
}
break;
case IDC_BRG:
__asm {
mov ebx, framebuffer;
mov ecx, c;
lp2:
sub ecx, 4;
mov eax, dword ptr [ebx+ecx*4];
mov dl, al;
shr eax, 8;
bswap eax;
mov ah, dl;
bswap eax;
mov [ebx+ecx*4], eax;
mov eax, dword ptr [ebx+ecx*4+4];
mov dl, al;
shr eax, 8;
bswap eax;
mov ah, dl;
bswap eax;
mov [ebx+ecx*4+4], eax;
mov eax, dword ptr [ebx+ecx*4+8];
mov dl, al;
shr eax, 8;
bswap eax;
mov ah, dl;
bswap eax;
mov [ebx+ecx*4+8], eax;
mov eax, dword ptr [ebx+ecx*4+12];
mov dl, al;
shr eax, 8;
bswap eax;
mov ah, dl;
bswap eax;
mov [ebx+ecx*4+12], eax;
test ecx, ecx;
jnz lp2;
}
break;
case IDC_BGR:
__asm {
mov ebx, framebuffer;
mov ecx, c;
lp3:
sub ecx, 4;
mov eax, dword ptr [ebx+ecx*4];
bswap eax;
shr eax, 8;
mov [ebx+ecx*4], eax;
mov eax, dword ptr [ebx+ecx*4+4];
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+4], eax;
mov eax, dword ptr [ebx+ecx*4+8];
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+8], eax;
mov eax, dword ptr [ebx+ecx*4+12];
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+12], eax;
test ecx, ecx;
jnz lp3;
}
break;
case IDC_GBR:
__asm {
mov ebx, framebuffer;
mov ecx, c;
lp4:
sub ecx, 4;
mov eax, dword ptr [ebx+ecx*4];
mov edx, eax;
bswap edx;
shl eax, 8;
mov al, dh;
mov [ebx+ecx*4], eax;
mov eax, dword ptr [ebx+ecx*4+4];
mov edx, eax;
bswap edx;
shl eax, 8;
mov al, dh;
mov [ebx+ecx*4+4], eax;
mov eax, dword ptr [ebx+ecx*4+8];
mov edx, eax;
bswap edx;
shl eax, 8;
mov al, dh;
mov [ebx+ecx*4+8], eax;
mov eax, dword ptr [ebx+ecx*4+12];
mov edx, eax;
bswap edx;
shl eax, 8;
mov al, dh;
mov [ebx+ecx*4+12], eax;
test ecx, ecx;
jnz lp4;
}
break;
case IDC_GRB:
__asm {
mov ebx, framebuffer;
mov ecx, c;
lp5:
sub ecx, 4;
mov eax, dword ptr [ebx+ecx*4];
shl eax, 8;
bswap eax;
xchg ah, al;
bswap eax;
shr eax, 8;
mov [ebx+ecx*4], eax;
mov eax, dword ptr [ebx+ecx*4+4];
shl eax, 8;
bswap eax;
xchg ah, al;
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+4], eax;
mov eax, dword ptr [ebx+ecx*4+8];
shl eax, 8;
bswap eax;
xchg ah, al;
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+8], eax;
mov eax, dword ptr [ebx+ecx*4+12];
shl eax, 8;
bswap eax;
xchg ah, al;
bswap eax;
shr eax, 8;
mov [ebx+ecx*4+12], eax;
test ecx, ecx;
jnz lp5;
}
break;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_CHANSHIFT, hwndParent, (DLGPROC)g_DlgProc);
}
char *C_THISCLASS::get_desc(void)
{
static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_CHANNEL_SHIFT,desc,128):desc);
}
void C_THISCLASS::load_config(unsigned char *data, int len)
{
srand((unsigned int)time(0));
if (len <= sizeof(apeconfig))
memcpy(&this->config, data, len);
}
int C_THISCLASS::save_config(unsigned char *data)
{
memcpy(data, &this->config, sizeof(apeconfig));
return sizeof(apeconfig);
}
C_RBASE *R_ChannelShift(char *desc)
{
if (desc) {
strcpy(desc,MOD_NAME);
return NULL;
}
return (C_RBASE *) new C_THISCLASS();
}
#endif
@@ -0,0 +1,231 @@
/*
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.
*/
#include <windows.h>
#include <stdlib.h>
#include <vfw.h>
#include <commctrl.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define MOD_NAME "Render / Clear screen"
#define C_THISCLASS C_ClearClass
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_CLEAR_SCREEN,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int enabled;
int onlyfirst;
int color;
int fcounter;
int blend, blendavg;
};
static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
C_THISCLASS::~C_THISCLASS()
{
}
// configuration read/write
C_THISCLASS::C_THISCLASS() // set up default configuration
{
color = 0;
onlyfirst = 0;
fcounter=0;
blend = 0;
blendavg = 0;
enabled=1;
}
#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) // read configuration of max length "len" from data.
{
int pos=0;
if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { color=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
if (len-pos >= 4) { onlyfirst=GET_INT(); pos+=4; }
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(color); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(blendavg); pos+=4;
PUT_INT(onlyfirst); pos+=4;
return pos;
}
// render function
// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
// w and h are the width and height of the screen, in pixels.
// isBeat is 1 if a beat has been detected.
// visdata is in the format of [spectrum:0,wave:1][channel][band].
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int i=w*h;
int *p=framebuffer;
if (!enabled) return 0;
if (onlyfirst && fcounter) return 0;
if (isBeat&0x80000000) return 0;
fcounter++;
if (blend==2) while (i--) BLEND_LINE(p++,color);
else if (blend) while (i--) *p++=BLEND(*p,color);
else if (blendavg) while (i--) *p++=BLEND_AVG(*p,color);
else while (i--) *p++=color;
return 0;
}
// configuration dialog stuff
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_ConfigThis->onlyfirst) CheckDlgButton(hwndDlg,IDC_CLEARFIRSTFRAME,BST_CHECKED);
if (g_ConfigThis->blend==1) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
else if (g_ConfigThis->blend==2) CheckDlgButton(hwndDlg,IDC_DEFRENDBLEND,BST_CHECKED);
else if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
return 1;
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL) // paint nifty color button
{
int w=di->rcItem.right-di->rcItem.left;
int _color=g_ConfigThis->color;
_color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
HPEN hPen,hOldPen;
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
hBrush = CreateBrushIndirect(&lb);
hOldPen=(HPEN)SelectObject(di->hDC,hPen);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
SelectObject(di->hDC,hOldPen);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
DeleteObject(hPen);
}
}
return 0;
case WM_COMMAND:
if ((LOWORD(wParam) == IDC_CHECK1) ||
(LOWORD(wParam) == IDC_ADDITIVE) ||
(LOWORD(wParam) == IDC_REPLACE) ||
(LOWORD(wParam) == IDC_5050) ||
(LOWORD(wParam) == IDC_DEFRENDBLEND))
{
g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
if (!g_ConfigThis->blend)
g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_DEFRENDBLEND)?2:0;
g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
}
if (LOWORD(wParam) == IDC_CLEARFIRSTFRAME)
{
g_ConfigThis->onlyfirst=IsDlgButtonChecked(hwndDlg,IDC_CLEARFIRSTFRAME)?1:0;
if (g_ConfigThis->onlyfirst) g_ConfigThis->fcounter=0;
}
if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
{
int *a=&(g_ConfigThis->color);
static COLORREF custcolors[16];
CHOOSECOLOR cs;
cs.lStructSize = sizeof(cs);
cs.hwndOwner = hwndDlg;
cs.hInstance = 0;
cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
cs.lpCustColors = custcolors;
cs.Flags = CC_RGBINIT|CC_FULLOPEN;
if (ChooseColor(&cs))
{
*a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
g_ConfigThis->color = *a;
}
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_CLEAR,hwndParent,g_DlgProc);
}
// export stuff
C_RBASE *R_Clear(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
#else
C_RBASE *R_Clear(char *desc) { return NULL; }
#endif
@@ -0,0 +1,357 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_ColorFadeClass
#define MOD_NAME "Trans / Colorfade"
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLORFADE,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
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
static int ft[4][3];
int enabled;
int faders[3];
int beatfaders[3];
int faderpos[3];
unsigned char c_tab[512][512];
unsigned char clip[256+40+40];
};
int C_THISCLASS::ft[4][3];
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { faders[0]=GET_INT(); pos+=4; }
if (len-pos >= 4) { faders[1]=GET_INT(); pos+=4; }
if (len-pos >= 4) { faders[2]=GET_INT(); pos+=4; }
memcpy(beatfaders,faders,3*sizeof(int));
if (len-pos >= 4) { beatfaders[0]=GET_INT(); pos+=4; }
if (len-pos >= 4) { beatfaders[1]=GET_INT(); pos+=4; }
if (len-pos >= 4) { beatfaders[2]=GET_INT(); pos+=4; }
memcpy(faderpos,faders,3*sizeof(int));
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(faders[0]); pos+=4;
PUT_INT(faders[1]); pos+=4;
PUT_INT(faders[2]); pos+=4;
PUT_INT(beatfaders[0]); pos+=4;
PUT_INT(beatfaders[1]); pos+=4;
PUT_INT(beatfaders[2]); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
int x,y;
enabled=1;
faders[0]=8;
faders[1]=faders[2]=-8;
memcpy(beatfaders,faders,3*sizeof(int));
memcpy(faderpos,faders,3*sizeof(int));
for (x = 0; x < 512; x ++)
{
for (y = 0; y < 512; y ++)
{
int xp=x-255;
int yp=y-255;
if (xp > 0 /* g-b > 0, or g > b */ && xp > -yp /* g-b > r-b, or g > r */ ) c_tab[x][y]=0;
else if (yp < 0 /* b-r < 0 or r > b */ && xp < -yp /* g-b < r-b, or g < r */ ) c_tab[x][y]=1;
else if (xp < 0 && yp > 0) c_tab[x][y]=2;
else c_tab[x][y]=3;
}
}
for (x = 0; x < 256+40+40; x ++)
clip[x]=min(max(x-40,0),255);
}
C_THISCLASS::~C_THISCLASS()
{
}
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);
}
int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (!enabled || (isBeat&0x80000000)) return 0;
if (faderpos[0] < faders[0]) faderpos[0]++;
if (faderpos[1] < faders[2]) faderpos[1]++;
if (faderpos[2] < faders[1]) faderpos[2]++;
if (faderpos[0] > faders[0]) faderpos[0]--;
if (faderpos[1] > faders[2]) faderpos[1]--;
if (faderpos[2] > faders[1]) faderpos[2]--;
if (!(enabled&4))
{
faderpos[0]=faders[0];
faderpos[1]=faders[1];
faderpos[2]=faders[2];
}
else if (isBeat && (enabled&2))
{
faderpos[0]=(rand()%32)-6;
faderpos[1]=(rand()%64)-32;
if (faderpos[1] < 0 && faderpos[1] > -16) faderpos[1]=-32;
if (faderpos[1] >= 0 && faderpos[1] < 16) faderpos[1]=32;
faderpos[2]=(rand()%32)-6;
}
else if (isBeat)
{
faderpos[0]=beatfaders[0];
faderpos[1]=beatfaders[1];
faderpos[2]=beatfaders[2];
}
{
int fs1,fs2,fs3;
fs1=faderpos[0];
fs2=faderpos[1];
fs3=faderpos[2];
ft[0][0]=fs3;
ft[0][1]=fs2;
ft[0][2]=fs1;
ft[1][0]=fs2;
ft[1][1]=fs1;
ft[1][2]=fs3;
ft[2][0]=fs1;
ft[2][1]=fs3;
ft[2][2]=fs2;
ft[3][0]=fs3;
ft[3][1]=fs3;
ft[3][2]=fs3;
}
return max_threads;
}
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 0;
}
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 (!enabled) return;
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;
unsigned char *q=(unsigned char *)(framebuffer + start_l*w);
unsigned char *ctab_ptr=(unsigned char *)c_tab[0]+255+(255<<9);
unsigned char *clip_ptr=(unsigned char *)clip+40;
int x=w*outh;
if (enabled)
{
int lx=x&1;
x>>=1;
while (x--)
{
int r=q[0];
int g=q[1];
int b=q[2];
int r2=q[4];
int g2=q[5];
int b2=q[6];
int i=((g-b)<<9) + b - r;
int i2=((g2-b2)<<9) + b2 - r2;
int p=ctab_ptr[i];
int p2=ctab_ptr[i2];
q[0]=clip_ptr[r+ft[p][0]];
q[1]=clip_ptr[g+ft[p][1]];
q[2]=clip_ptr[b+ft[p][2]];
q[4]=clip_ptr[r2+ft[p2][0]];
q[5]=clip_ptr[g2+ft[p2][1]];
q[6]=clip_ptr[b2+ft[p2][2]];
q+=8;
}
if (lx)
{
int r=q[0];
int g=q[1];
int b=q[2];
int i=((g-b)<<9) + b - r;
int p=ctab_ptr[i];
q[0]=clip_ptr[r+ft[p][0]];
q[1]=clip_ptr[g+ft[p][1]];
q[2]=clip_ptr[b+ft[p][2]];
}
}
}
C_RBASE *R_ColorFade(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)
{
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->faders[0]+32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->faders[1]+32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->faders[2]+32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->beatfaders[0]+32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETPOS,1,g_this->beatfaders[1]+32);
SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMAX,0,64);
SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETPOS,1,g_this->beatfaders[2]+32);
if (g_this->enabled&1) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_this->enabled&2) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
if (g_this->enabled&4) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CHECK1:
case IDC_CHECK2:
case IDC_CHECK3:
g_this->enabled=(IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0)|
(IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?2:0)|
(IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?4:0);
return 0;
}
return 0;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->faders[0]=t-32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
{
g_this->faders[1]=t-32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
{
g_this->faders[2]=t-32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
{
g_this->beatfaders[0]=t-32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER5))
{
g_this->beatfaders[1]=t-32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER6))
{
g_this->beatfaders[2]=t-32;
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_COLORFADE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_ColorFade(char *desc) { return NULL; }
#endif
@@ -0,0 +1,193 @@
/*
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.
*/
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
// this will be the directory and APE name displayed in the AVS Editor
#define MOD_NAME "Trans / Color Reduction"
#define C_THISCLASS C_ColorReduction
typedef struct {
char fname[MAX_PATH];
int levels;
} apeconfig;
class C_THISCLASS : public C_RBASE
{
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 HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual char *get_desc();
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
apeconfig config;
HWND hwndDlg;
};
// global configuration dialog pointer
static C_THISCLASS *g_ConfigThis;
static HINSTANCE g_hDllInstance;
// this is where we deal with the configuration screen
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_HSCROLL:
{
if (LOWORD(wParam) == TB_ENDTRACK)
g_ConfigThis->config.levels = SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_GETPOS, 0, 0);
{
char buf[4];
int a,b;
a = 8-g_ConfigThis->config.levels;
b = 0x100;
while (a--) b>>=1;
wsprintf(buf, "%d", b);
SetDlgItemText(hwndDlg, IDC_LEVELTEXT, buf);
}
}
return 1;
case WM_INITDIALOG:
g_ConfigThis->hwndDlg = hwndDlg;
SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_SETRANGE, TRUE, MAKELONG(1, 8));
SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_SETPOS, TRUE, g_ConfigThis->config.levels);
SetFocus(GetDlgItem(hwndDlg, IDC_LEVELS));
{
char buf[4];
int a,b;
a = 8-g_ConfigThis->config.levels;
b = 0x100;
while (a--) b>>=1;
wsprintf(buf, "%d", b);
SetDlgItemText(hwndDlg, IDC_LEVELTEXT, buf);
}
return 1;
case WM_DESTROY:
KillTimer(hwndDlg, 1);
return 1;
}
return 0;
}
// set up default configuration
C_THISCLASS::C_THISCLASS()
{
memset(&config, 0, sizeof(apeconfig));
config.levels = 7;
}
// virtual destructor
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (isBeat&0x80000000) return 0;
int a,b,c;
a = 8-config.levels;
b = 0xFF;
while (a--) b=(b<<1)&0xFF;
b |= (b<<16) | (b<<8);
c = w*h;
__asm {
mov ebx, framebuffer;
mov ecx, c;
mov edx, b;
lp:
sub ecx, 4;
test ecx, ecx;
jz end;
and dword ptr [ebx+ecx*4], edx;
and dword ptr [ebx+ecx*4+4], edx;
and dword ptr [ebx+ecx*4+8], edx;
and dword ptr [ebx+ecx*4+12], edx;
jmp lp;
end:
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_ConfigThis = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_COLORREDUCTION, hwndParent, (DLGPROC)g_DlgProc);
}
char *C_THISCLASS::get_desc(void)
{
static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_REDUCTION,desc,128):desc);
}
void C_THISCLASS::load_config(unsigned char *data, int len)
{
if (len == sizeof(apeconfig))
memcpy(&this->config, data, len);
else
memset(&this->config, 0, sizeof(apeconfig));
}
int C_THISCLASS::save_config(unsigned char *data)
{
memcpy(data, &this->config, sizeof(apeconfig));
return sizeof(apeconfig);
}
C_RBASE *R_ColorReduction(char *desc)
{
if (desc) {
strcpy(desc,MOD_NAME);
return NULL;
}
return (C_RBASE *) new C_THISCLASS();
}
#endif
@@ -0,0 +1,159 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#define C_THISCLASS C_ContrastEnhanceClass
#define MOD_NAME "Trans / Color Clip"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_CLIP,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int enabled;
int color_clip;
};
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { color_clip=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(color_clip); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
enabled=1;
color_clip=RGB(32,32,32);
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
unsigned int *f = (unsigned int *) framebuffer;
int fs_r,fs_g,fs_b;
int x=w*h;
if (!enabled) return 0;
fs_b=(color_clip>>16)&255;
fs_g=(color_clip>>8)&255;
fs_r=(color_clip)&255;
while (x--)
{
int r=f[0]&255;
int g=(f[0]>>8)&255;
int b=(f[0]>>16)&255;
int a=(f[0]&0xff000000);
if (r <= fs_r && g <= fs_g && b <= fs_b)
f[0]=a|fs_r|(fs_g<<8)|(fs_b<<16);
f++;
}
return 0;
}
C_RBASE *R_ContrastEnhance(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)
{
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
switch (di->CtlID)
{
case IDC_LC:
GR_DrawColoredButton(di,g_this->color_clip);
break;
}
}
return 0;
case WM_INITDIALOG:
if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CHECK1:
g_this->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
return 0;
case IDC_LC:
GR_SelectColor(hwndDlg,&g_this->color_clip);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
return 0;
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_CONTRASTENHANCE,hwndParent,g_DlgProc);
}
@@ -0,0 +1,116 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#define C_THISCLASS C_CommentClass
#define MOD_NAME "Misc / Comment"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_COMMENT,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
RString msgdata;
};
#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;
load_string(msgdata,data,pos,len);
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
save_string(data,pos,msgdata);
return pos;
}
C_THISCLASS::C_THISCLASS()
{
msgdata.assign("");
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
return 0;
}
C_RBASE *R_Comment(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)
{
switch (uMsg)
{
case WM_INITDIALOG:
SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->msgdata.get());
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_EDIT1 && HIWORD(wParam) == EN_CHANGE)
{
g_this->msgdata.get_from_dlgitem(hwndDlg,IDC_EDIT1);
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_COMMENT,hwndParent,g_DlgProc);
}
@@ -0,0 +1,226 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_ContrastEnhanceClass
#define MOD_NAME "Trans / Color Clip"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_CLIP,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int enabled;
int color_clip,color_clip_out,color_dist;
};
#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) { enabled=GET_INT(); pos+=4; }
if (len-pos >= 4) { color_clip=GET_INT(); pos+=4; }
if (len-pos >= 4) { color_clip_out=GET_INT(); pos+=4; }
else color_clip_out=color_clip;
if (len-pos >= 4) { color_dist=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(enabled); pos+=4;
PUT_INT(color_clip); pos+=4;
PUT_INT(color_clip_out); pos+=4;
PUT_INT(color_dist); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
enabled=1;
color_clip=RGB(32,32,32);
color_clip_out=RGB(32,32,32);
color_dist=10;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (!enabled) return 0;
if (isBeat&0x80000000) return 0;
int *f = framebuffer;
int fs_r,fs_g,fs_b;
int x=w*h;
int l=color_dist*2;
l=l*l;
fs_b=(color_clip&0xff0000);
fs_g=(color_clip&0xff00);
fs_r=(color_clip&0xff);
if (enabled==1) while (x--)
{
int a=f[0];
if ((a&0xff) <= fs_r && (a&0xff00) <= fs_g && (a&0xff0000) <= fs_b)
f[0]=(a&0xff000000)|color_clip_out;
f++;
}
else if (enabled==2) while (x--)
{
int a=f[0];
if ((a&0xff) >= fs_r && (a&0xff00) >= fs_g && (a&0xff0000) >= fs_b)
f[0]=(a&0xff000000)|color_clip_out;
f++;
}
else
{
fs_b>>=16;
fs_g>>=8;
while (x--)
{
int a=f[0];
int r=a&255;
int g=(a>>8)&255;
int b=(a>>16)&255;
r-=fs_r; g-=fs_g; b-=fs_b;
if (r*r+g*g+b*b <= l) f[0]=(a&0xff000000)|color_clip_out;
f++;
}
}
return 0;
}
C_RBASE *R_ContrastEnhance(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)
{
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
switch (di->CtlID)
{
case IDC_LC:
GR_DrawColoredButton(di,g_this->color_clip);
break;
case IDC_LC2:
GR_DrawColoredButton(di,g_this->color_clip_out);
break;
}
}
return 0;
case WM_INITDIALOG:
if (g_this->enabled==0) CheckDlgButton(hwndDlg,IDC_OFF,BST_CHECKED);
else if (g_this->enabled==1) CheckDlgButton(hwndDlg,IDC_BELOW,BST_CHECKED);
else if (g_this->enabled==2) CheckDlgButton(hwndDlg,IDC_ABOVE,BST_CHECKED);
else CheckDlgButton(hwndDlg,IDC_NEAR,BST_CHECKED);
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETPOS, TRUE, g_this->color_dist);
SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETTICFREQ, 4, 0);
return 1;
case WM_NOTIFY:
if (LOWORD(wParam) == IDC_DISTANCE)
g_this->color_dist = SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_GETPOS, 0, 0);
return 0;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_OFF:
case IDC_BELOW:
case IDC_ABOVE:
case IDC_NEAR:
if (IsDlgButtonChecked(hwndDlg,IDC_OFF))
g_this->enabled=0;
else if (IsDlgButtonChecked(hwndDlg,IDC_BELOW))
g_this->enabled=1;
else if (IsDlgButtonChecked(hwndDlg,IDC_ABOVE))
g_this->enabled=2;
else
g_this->enabled=3;
return 0;
case IDC_LC:
GR_SelectColor(hwndDlg,&g_this->color_clip);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
return 0;
case IDC_LC2:
GR_SelectColor(hwndDlg,&g_this->color_clip_out);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
return 0;
case IDC_BUTTON1:
g_this->color_clip_out=g_this->color_clip;
InvalidateRect(GetDlgItem(hwndDlg,IDC_LC2),NULL,FALSE);
return 0;
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_CONTRASTENHANCE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_ContrastEnhance(char *desc) { return NULL; }
#endif
@@ -0,0 +1,359 @@
/*
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.
*/
#include <windows.h>
#include <commctrl.h>
#include <math.h>
#include "r_defs.h"
#include "resource.h"
#include "avs_eelif.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_DColorModClass
#define MOD_NAME "Trans / Color Modifier"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_MODIFIER,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
RString effect_exp[4];
int m_recompute;
int m_tab_valid;
unsigned char m_tab[768];
NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
double *var_r, *var_g, *var_b, *var_beat;
int inited;
NSEEL_CODEHANDLE codehandle[4];
int need_recompile;
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 (data[pos] == 1)
{
pos++;
load_string(effect_exp[0],data,pos,len);
load_string(effect_exp[1],data,pos,len);
load_string(effect_exp[2],data,pos,len);
load_string(effect_exp[3],data,pos,len);
}
else
{
char buf[1025];
if (len-pos >= 1024)
{
memcpy(buf,data+pos,1024);
pos+=1024;
buf[1024]=0;
effect_exp[3].assign(buf+768);
buf[768]=0;
effect_exp[2].assign(buf+512);
buf[512]=0;
effect_exp[1].assign(buf+256);
buf[256]=0;
effect_exp[0].assign(buf);
}
}
if (len-pos >= 4) { m_recompute=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
data[pos++]=1;
save_string(data,pos,effect_exp[0]);
save_string(data,pos,effect_exp[1]);
save_string(data,pos,effect_exp[2]);
save_string(data,pos,effect_exp[3]);
PUT_INT(m_recompute); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
AVS_EEL_INITINST();
InitializeCriticalSection(&rcs);
need_recompile=1;
m_recompute=1;
memset(codehandle,0,sizeof(codehandle));
effect_exp[0].assign("");
effect_exp[1].assign("");
effect_exp[2].assign("");
effect_exp[3].assign("");
var_beat=0;
m_tab_valid=0;
}
C_THISCLASS::~C_THISCLASS()
{
int x;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=0;
}
AVS_EEL_QUITINST();
DeleteCriticalSection(&rcs);
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (need_recompile)
{
EnterCriticalSection(&rcs);
if (!var_beat || g_reset_vars_on_recompile)
{
clearVars();
var_r = registerVar("red");
var_g = registerVar("green");
var_b = registerVar("blue");
var_beat = registerVar("beat");
inited=0;
}
need_recompile=0;
int x;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=compileCode(effect_exp[x].get());
}
LeaveCriticalSection(&rcs);
}
if (isBeat&0x80000000) return 0;
*var_beat=isBeat?1.0:0.0;
if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
executeCode(codehandle[1],visdata);
if (isBeat) executeCode(codehandle[2],visdata);
if (m_recompute || !m_tab_valid)
{
int x;
unsigned char *t=m_tab;
for (x = 0; x < 256; x ++)
{
*var_r=*var_b=*var_g=x/255.0;
executeCode(codehandle[0],visdata);
int r=(int) (*var_r*255.0 + 0.5);
int g=(int) (*var_g*255.0 + 0.5);
int b=(int) (*var_b*255.0 + 0.5);
if (r < 0) r=0;
else if (r > 255)r=255;
if (g < 0) g=0;
else if (g > 255)g=255;
if (b < 0) b=0;
else if (b > 255)b=255;
t[512]=r;
t[256]=g;
t[0]=b;
t++;
}
m_tab_valid=1;
}
unsigned char *fb=(unsigned char *)framebuffer;
int l=w*h;
while (l--)
{
fb[0]=m_tab[fb[0]];
fb[1]=m_tab[(int)fb[1]+256];
fb[2]=m_tab[(int)fb[2]+512];
fb+=4;
}
return 0;
}
C_RBASE *R_DColorMod(char *desc)
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
typedef struct
{
char *name;
char *init;
char *point;
char *frame;
char *beat;
int recompute;
} presetType;
static presetType presets[]=
{
// Name, Init, Level, Frame, Beat, Recalc
{"4x Red Brightness, 2x Green, 1x Blue","","red=4*red; green=2*green;","","",0},
{"Solarization","","red=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","","",0},
{"Double Solarization","","red=(min(1,red*2)-red)*2;\r\nred=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","","",0},
{"Inverse Solarization (Soft)","","red=abs(red - .5) * 1.5;\r\ngreen=red; blue=red;","","",0},
{"Big Brightness on Beat","scale=1.0","red=red*scale;\r\ngreen=red; blue=red;","scale=0.07 + (scale*0.93)","scale=16",1},
{"Big Brightness on Beat (Interpolative)","c = 200; f = 0;","red = red * t;\r\ngreen=red;blue=red;","f = f + 1;\r\nt = (1.025 - (f / c)) * 5;","c = f;f = 0;",1},
{"Pulsing Brightness (Beat Interpolative)","c = 200; f = 0;","red = red * st;\r\ngreen=red;blue=red;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nst = sin(t) + 1;","c = f;f = 0;",1},
{"Rolling Solarization (Beat Interpolative)","c = 200; f = 0;","red=(min(1,red*st)-red)*st;\r\nred=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nst = ( sin(t) * .75 ) + 2;","c = f;f = 0;",1},
{"Rolling Tone (Beat Interpolative)","c = 200; f = 0;","red = red * st;\r\ngreen = green * ct;\r\nblue = (blue * 4 * ti) - red - green;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nti = (f / c);\r\nst = sin(t) + 1.5;\r\nct = cos(t) + 1.5;","c = f;f = 0;",1},
{"Random Inverse Tone (Switch on Beat)","","dd = red * 1.5;\r\nred = pow(dd, dr);\r\ngreen = pow(dd, dg);\r\nblue = pow(dd, db);","","token = rand(99) % 3;\r\ndr = if (equal(token, 0), -1, 1);\r\ndg = if (equal(token, 1), -1, 1);\r\ndb = if (equal(token, 2), -1, 1);",1},
};
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:
isstart=1;
SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
if (g_this->m_recompute)
CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
isstart=0;
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_BUTTON1)
{
/* char text[4096];
WASABI_API_LNGSTRING_BUF(IDS_COLOR_MODIFIER,text,4096);
int titlelen = lstrlen(text)+1;
lstrcpyn(text+titlelen,GetTextResource(IDR_COLOR_MODIFIER),4095-titlelen);
*/
char *text="Color Modifier\0"
"The color modifier allows you to modify the intensity of each color\r\n"
"channel with respect to itself. For example, you could reverse the red\r\n"
"channel, double the green channel, or half the blue channel.\r\n"
"\r\n"
"The code in the 'level' section should adjust the variables\r\n"
"'red', 'green', and 'blue', whose value represent the channel\r\n"
"intensity (0..1).\r\n"
"Code in the 'frame' or 'level' sections can also use the variable\r\n"
"'beat' to detect if it is currently a beat.\r\n"
"\r\n"
"Try loading an example via the 'Load Example' button for examples."
;
compilerfunctionlist(hwndDlg,text);
}
if (LOWORD(wParam)==IDC_CHECK1)
{
g_this->m_recompute=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
}
if (LOWORD(wParam) == IDC_BUTTON4)
{
RECT r;
HMENU hMenu;
MENUITEMINFO i={sizeof(i),};
hMenu=CreatePopupMenu();
int x;
for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
{
i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
i.fType=MFT_STRING;
i.wID = x+16;
i.dwTypeData=presets[x].name;
i.cch=strlen(presets[x].name);
InsertMenuItem(hMenu,x,TRUE,&i);
}
GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON4),&r);
x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
{
isstart=1;
SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
g_this->m_recompute=presets[x-16].recompute;
CheckDlgButton(hwndDlg,IDC_CHECK1,g_this->m_recompute?BST_CHECKED:0);
isstart=0;
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
}
DestroyMenu(hMenu);
}
if (!isstart && HIWORD(wParam) == EN_CHANGE)
{
if (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4)
{
EnterCriticalSection(&g_this->rcs);
g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
g_this->need_recompile=1;
if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
g_this->m_tab_valid=0;
LeaveCriticalSection(&g_this->rcs);
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_COLORMOD,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DColorMod(char *desc) { return NULL; }
#endif
+492
View File
@@ -0,0 +1,492 @@
/*
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.
*/
#define M_PI 3.14159265358979323846
#include <windows.h>
#include <commctrl.h>
#include <math.h>
#include "r_defs.h"
#include "resource.h"
#include "avs_eelif.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_PulseClass
#define MOD_NAME "Trans / Dynamic Distance Modifier"
// Integer Square Root function
// Uses factoring to find square root
// A 256 entry table used to work out the square root of the 7 or 8 most
// significant bits. A power of 2 used to approximate the rest.
// Based on an 80386 Assembly implementation by Arne Steinarson
static unsigned const char sq_table[]=
{0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, 64, 65,
67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89, 90, 91, 93, 94,
96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113,
114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153,
154, 155, 155, 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164,
165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175,
176, 176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185,
185, 186, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 193, 194,
195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202, 203, 203,
204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, 212,
212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220,
221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228,
229, 229, 230, 230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236,
236, 237, 237, 238, 238, 239, 240, 240, 241, 241, 242, 242, 243, 243,
244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250,
251, 251, 252, 252, 253, 253, 254, 254, 255};
static __inline unsigned long isqrt(unsigned long n)
{
if (n >= 0x10000)
if (n >= 0x1000000)
if (n >= 0x10000000)
if (n >= 0x40000000) return(sq_table[n >> 24] << 8);
else return(sq_table[n >> 22] << 7);
else
if (n >= 0x4000000) return(sq_table[n >> 20] << 6);
else return(sq_table[n >> 18] << 5);
else
if (n >= 0x100000)
if (n >= 0x400000) return(sq_table[n >> 16] << 4);
else return(sq_table[n >> 14] << 3);
else
if (n >= 0x40000) return(sq_table[n >> 12] << 2);
else return(sq_table[n >> 10] << 1);
else
if (n >= 0x100)
if (n >= 0x1000)
if (n >= 0x4000) return(sq_table[n >> 8]);
else return(sq_table[n >> 6] >> 1);
else
if (n >= 0x400) return(sq_table[n >> 4] >> 2);
else return(sq_table[n >> 2] >> 3);
else
if (n >= 0x10)
if (n >= 0x40) return(sq_table[n] >> 4);
else return(sq_table[n << 2] << 5);
else
if (n >= 0x4) return(sq_table[n >> 4] << 6);
else return(sq_table[n >> 6] << 7);
}
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_DISTANCE_MODIFIER,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
RString effect_exp[4];
int blend;
int m_wt;
int m_lastw,m_lasth;
int *m_wmul;
int *m_tab;
NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
double *var_d, *var_b;
double max_d;
int inited;
NSEEL_CODEHANDLE codehandle[4];
int need_recompile;
int subpixel;
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 (data[pos] == 1)
{
pos++;
load_string(effect_exp[0],data,pos,len);
load_string(effect_exp[1],data,pos,len);
load_string(effect_exp[2],data,pos,len);
load_string(effect_exp[3],data,pos,len);
}
else
{
char buf[513];
if (len-pos >= 256*2)
{
memcpy(buf,data+pos,256*2);
pos+=256*2;
buf[512]=0;
effect_exp[1].assign(buf+256);
buf[256]=0;
effect_exp[0].assign(buf);
}
if (len-pos >= 256*2)
{
memcpy(buf,data+pos,256*2);
pos+=256*2;
buf[512]=0;
effect_exp[3].assign(buf+256);
buf[256]=0;
effect_exp[2].assign(buf);
}
}
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
data[pos++]=1;
save_string(data,pos,effect_exp[0]);
save_string(data,pos,effect_exp[1]);
save_string(data,pos,effect_exp[2]);
save_string(data,pos,effect_exp[3]);
PUT_INT(blend); pos+=4;
PUT_INT(subpixel); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
AVS_EEL_INITINST();
InitializeCriticalSection(&rcs);
need_recompile=1;
memset(codehandle,0,sizeof(codehandle));
m_lasth=m_lastw=0;
m_wmul=0;
m_tab=0;
m_wt=0;
effect_exp[0].assign("d=d-sigmoid((t-50)/100,2)");
effect_exp[3].assign("u=1;t=0");
effect_exp[1].assign("t=t+u;t=min(100,t);t=max(0,t);u=if(equal(t,100),-1,u);u=if(equal(t,0),1,u)");
effect_exp[2].assign("");
blend=0;
subpixel=0;
var_b=0;
}
C_THISCLASS::~C_THISCLASS()
{
int x;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=0;
}
if (m_wmul) GlobalFree(m_wmul);
if (m_tab) GlobalFree(m_tab);
AVS_EEL_QUITINST();
m_tab=0;
m_wmul=0;
DeleteCriticalSection(&rcs);
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int *fbin=framebuffer;
if (m_lasth != h || m_lastw != w || !m_tab || !m_wmul)
{
int y;
m_lastw=w; // jf 121100 - added (oops)
m_lasth=h;
max_d=sqrt((w*w+h*h)/4.0);
if (m_wmul) GlobalFree(m_wmul);
m_wmul=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
for (y = 0; y < h; y ++) m_wmul[y]=y*w;
if (m_tab) GlobalFree(m_tab);
m_tab=0;
}
int imax_d=(int)(max_d + 32.9);
if (imax_d < 33) imax_d=33;
if (!m_tab)
m_tab=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*imax_d);
int x;
//pow(sin(d),dpos)*1.7
if (need_recompile)
{
EnterCriticalSection(&rcs);
if (!var_b || g_reset_vars_on_recompile)
{
clearVars();
var_d = registerVar("d");
var_b = registerVar("b");
inited=0;
}
need_recompile=0;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=compileCode(effect_exp[x].get());
}
LeaveCriticalSection(&rcs);
}
if (isBeat&0x80000000) return 0;
*var_b=isBeat?1.0:0.0;
if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
executeCode(codehandle[1],visdata);
if (isBeat) executeCode(codehandle[2],visdata);
if (codehandle[0])
{
for (x = 0; x < imax_d-32; x ++)
{
*var_d=x/(max_d-1);
executeCode(codehandle[0],visdata);
m_tab[x]=(int) (*var_d*256.0*max_d/(x+1));
}
for (; x < imax_d; x ++)
{
m_tab[x]=m_tab[x-1];
}
}
else for (x = 0; x < imax_d; x ++) m_tab[x]=0;
m_wt++;
m_wt&=63;
{
int w2=w/2;
int h2=h/2;
int y;
for (y = 0; y < h; y ++)
{
int ty=y-h2;
int x2=w2*w2+w2+ty*ty+256;
int dx2=-2*w2;
int yysc=ty;
int xxsc=-w2;
int x=w;
if (subpixel)
{
if (blend)
while (x--)
{
int qd=m_tab[isqrt(x2)];
int ow,oh;
int xpart,ypart;
x2+=dx2;
dx2+=2;
xpart=(qd*xxsc+128);
ypart=(qd*yysc+128);
ow = w2 + (xpart>>8);
oh = h2 + (ypart>>8);
xpart&=0xff;
ypart&=0xff;
xxsc++;
if (ow < 0) ow=0;
else if (ow >= w-1) ow=w-2;
if (oh < 0) oh=0;
else if (oh >= h-1) oh=h-2;
*fbout++=BLEND_AVG(BLEND4((unsigned int *)framebuffer+ow+m_wmul[oh],w,xpart,ypart),*fbin++);
}
else
while (x--)
{
int qd=m_tab[isqrt(x2)];
int ow,oh;
int xpart,ypart;
x2+=dx2;
dx2+=2;
xpart=(qd*xxsc+128);
ypart=(qd*yysc+128);
ow = w2 + (xpart>>8);
oh = h2 + (ypart>>8);
xpart&=0xff;
ypart&=0xff;
xxsc++;
if (ow < 0) ow=0;
else if (ow >= w-1) ow=w-2;
if (oh < 0) oh=0;
else if (oh >= h-1) oh=h-2;
*fbout++=BLEND4((unsigned int *)framebuffer+ow+m_wmul[oh],w,xpart,ypart);
}
}
else
{
if (blend)
while (x--)
{
int qd=m_tab[isqrt(x2)];
int ow,oh;
x2+=dx2;
dx2+=2;
ow = w2 + ((qd*xxsc+128)>>8);
xxsc++;
oh = h2 + ((qd*yysc+128)>>8);
if (ow < 0) ow=0;
else if (ow >= w) ow=w-1;
if (oh < 0) oh=0;
else if (oh >= h) oh=h-1;
*fbout++=BLEND_AVG(framebuffer[ow+m_wmul[oh]],*fbin++);
}
else
while (x--)
{
int qd=m_tab[isqrt(x2)];
int ow,oh;
x2+=dx2;
dx2+=2;
ow = w2 + ((qd*xxsc+128)>>8);
xxsc++;
oh = h2 + ((qd*yysc+128)>>8);
if (ow < 0) ow=0;
else if (ow >= w) ow=w-1;
if (oh < 0) oh=0;
else if (oh >= h) oh=h-1;
*fbout++=framebuffer[ow+m_wmul[oh]];
}
}
}
}
#ifndef NO_MMX
if (subpixel) __asm emms;
#endif
return 1;
}
C_RBASE *R_DDM(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:
isstart=1;
SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
isstart=0;
if (g_this->blend)
CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_this->subpixel)
CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_BUTTON1)
{
/* char text[4096];
WASABI_API_LNGSTRING_BUF(IDS_DYNAMIC_DISTANCE_MODIFIER,text,4096);
int titlelen = lstrlen(text)+1;
lstrcpyn(text+titlelen,GetTextResource(IDR_DYNAMIC_DISTANCE_MODIFIER),4095-titlelen);
*/
char *text="Dynamic Distance Modifier\0"
"The dynamic distance modifier allows you to dynamically (once per frame)\r\n"
"change the source pixels for each ring of pixels out from the center.\r\n"
"In the 'pixel' code section, 'd' represents the distance in pixels\r\n"
"the current ring is from the center, and code can modify it to\r\n"
"change the distance from the center where the source pixels for\r\n"
"that ring would be read. This is a terrible explanation, and if\r\n"
"you want to make a better one send it to me. \r\n"
"\r\n"
"Examples:\r\n"
"Zoom in: 'd=d*0.9'\r\n"
"Zoom out: 'd=d*1.1'\r\n"
"Back and forth: pixel='d=d*(1.0+0.1*cos(t));', frame='t=t+0.1'\r\n"
;
compilerfunctionlist(hwndDlg,text);
}
if (LOWORD(wParam)==IDC_CHECK1)
{
g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
}
if (LOWORD(wParam)==IDC_CHECK2)
{
g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
}
if (!isstart && (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4) && HIWORD(wParam) == EN_CHANGE)
{
EnterCriticalSection(&g_this->rcs);
g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
g_this->need_recompile=1;
if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
LeaveCriticalSection(&g_this->rcs);
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_DDM,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DDM(char *desc) { return NULL; }
#endif
+739
View File
@@ -0,0 +1,739 @@
/*
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
@@ -0,0 +1,780 @@
/*
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.
*/
#define M_PI 3.14159265358979323846
#include <windows.h>
#include <commctrl.h>
#include <math.h>
#include "r_defs.h"
#include "resource.h"
#include "avs_eelif.h"
#include "r_list.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#if 0
static void __docheck(int xp, int yp, int m_lastw, int m_lasth, int d_x, int d_y)
{
xp >>= 16;
yp >>= 16;
if (xp < 0 || xp >= m_lastw || yp < 0 || yp >= m_lasth)
{
char buf[512];
wsprintf(buf,"@ %d,%d on %d,%d (dx,dy=%d,%d)\n",xp,yp,m_lastw,m_lasth,d_x,d_y);
OutputDebugString(buf);
}
}
#endif
#ifndef LASER
#define C_THISCLASS C_DMoveClass
#define MOD_NAME "Trans / Dynamic Movement"
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() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_MOVEMENT,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
RString effect_exp[4];
int m_lastw,m_lasth;
int m_lastxres, m_lastyres, m_xres, m_yres;
int *m_wmul;
int *m_tab;
NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
double *var_d, *var_b, *var_r, *var_x, *var_y, *var_w, *var_h, *var_alpha;
int inited;
NSEEL_CODEHANDLE codehandle[4];
int need_recompile;
int buffern;
int subpixel,rectcoords,blend,wrap, nomove;
CRITICAL_SECTION rcs;
// smp stuff
int __subpixel,__rectcoords,__blend,__wrap, __nomove;
int w_adj;
int h_adj;
int XRES;
int YRES;
};
#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 (data[pos] == 1)
{
pos++;
load_string(effect_exp[0],data,pos,len);
load_string(effect_exp[1],data,pos,len);
load_string(effect_exp[2],data,pos,len);
load_string(effect_exp[3],data,pos,len);
}
else
{
char buf[1025];
if (len-pos >= 1024)
{
memcpy(buf,data+pos,1024);
pos+=1024;
buf[1024]=0;
effect_exp[3].assign(buf+768);
buf[768]=0;
effect_exp[2].assign(buf+512);
buf[512]=0;
effect_exp[1].assign(buf+256);
buf[256]=0;
effect_exp[0].assign(buf);
}
}
if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
if (len-pos >= 4) { rectcoords=GET_INT(); pos+=4; }
if (len-pos >= 4) { m_xres=GET_INT(); pos+=4; }
if (len-pos >= 4) { m_yres=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
if (len-pos >= 4) { wrap=GET_INT(); pos+=4; }
if (len-pos >= 4) { buffern=GET_INT(); pos+=4; }
else buffern=0;
if (len-pos >= 4) { nomove=GET_INT(); pos+=4; }
else nomove=0;
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
data[pos++]=1;
save_string(data,pos,effect_exp[0]);
save_string(data,pos,effect_exp[1]);
save_string(data,pos,effect_exp[2]);
save_string(data,pos,effect_exp[3]);
PUT_INT(subpixel); pos+=4;
PUT_INT(rectcoords); pos+=4;
PUT_INT(m_xres); pos+=4;
PUT_INT(m_yres); pos+=4;
PUT_INT(blend); pos+=4;
PUT_INT(wrap); pos+=4;
PUT_INT(buffern); pos+=4;
PUT_INT(nomove); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
AVS_EEL_INITINST();
InitializeCriticalSection(&rcs);
need_recompile=1;
memset(codehandle,0,sizeof(codehandle));
m_lasth=m_lastw=0;
m_wmul=0;
m_tab=0;
effect_exp[0].assign("");
effect_exp[1].assign("");
effect_exp[2].assign("");
effect_exp[3].assign("");
m_lastxres=m_lastyres=0;
m_xres=16;
m_yres=16;
var_b=0;
subpixel=1;
rectcoords=0;
blend=0;
wrap=0;
buffern=0;
nomove=0;
}
C_THISCLASS::~C_THISCLASS()
{
int x;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=0;
}
AVS_EEL_QUITINST();
if (m_wmul) GlobalFree(m_wmul);
if (m_tab) GlobalFree(m_tab);
m_tab=0;
m_wmul=0;
DeleteCriticalSection(&rcs);
}
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);
}
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 !__nomove;
}
int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
__subpixel=subpixel;
__rectcoords=rectcoords;
__blend=blend;
__wrap=wrap;
__nomove=nomove;
w_adj=(w-2)<<16;
h_adj=(h-2)<<16;
XRES=m_xres+1;
YRES=m_yres+1;
if (XRES < 2) XRES=2;
if (XRES > 256) XRES=256;
if (YRES < 2) YRES=2;
if (YRES > 256) YRES=256;
if (m_lasth != h || m_lastw != w || !m_tab || !m_wmul ||
m_lastxres != XRES || m_lastyres != YRES)
{
int y;
m_lastxres = XRES;
m_lastyres = YRES;
m_lastw=w;
m_lasth=h;
if (m_wmul) GlobalFree(m_wmul);
m_wmul=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
for (y = 0; y < h; y ++) m_wmul[y]=y*w;
if (m_tab) GlobalFree(m_tab);
m_tab=(int*)GlobalAlloc(GMEM_FIXED,(XRES*YRES*3 + (XRES*6 + 6)*MAX_SMP_THREADS)*sizeof(int));
}
if (!__subpixel)
{
w_adj=(w-1)<<16;
h_adj=(h-1)<<16;
}
if (need_recompile)
{
int x;
int err=0;
EnterCriticalSection(&rcs);
if (!var_b || g_reset_vars_on_recompile)
{
clearVars();
var_d = registerVar("d");
var_b = registerVar("b");
var_r = registerVar("r");
var_x = registerVar("x");
var_y = registerVar("y");
var_w = registerVar("w");
var_h = registerVar("h");
var_alpha = registerVar("alpha");
inited=0;
}
need_recompile=0;
for (x = 0; x < 4; x ++)
{
freeCode(codehandle[x]);
codehandle[x]=compileCode(effect_exp[x].get());
}
LeaveCriticalSection(&rcs);
}
if (isBeat&0x80000000) return 0;
int *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
if (!fbin) return 0;
*var_w=(double)w;
*var_h=(double)h;
*var_b=isBeat?1.0:0.0;
*var_alpha=0.5;
if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
executeCode(codehandle[1],visdata);
if (isBeat) executeCode(codehandle[2],visdata);
{
int x;
int y;
int *tabptr=m_tab;
double xsc=2.0/w,ysc=2.0/h;
double dw2=((double)w*32768.0);
double dh2=((double)h*32768.0);
double max_screen_d=sqrt((double)(w*w+h*h))*0.5;
double divmax_d=1.0/max_screen_d;
max_screen_d *= 65536.0;
int yc_pos, yc_dpos, xc_pos, xc_dpos;
yc_pos=0;
xc_dpos = (w<<16)/(XRES-1);
yc_dpos = (h<<16)/(YRES-1);
for (y = 0; y < YRES; y ++)
{
xc_pos=0;
for (x = 0; x < XRES; x ++)
{
double xd,yd;
xd=((double)xc_pos-dw2)*(1.0/65536.0);
yd=((double)yc_pos-dh2)*(1.0/65536.0);
xc_pos+=xc_dpos;
*var_x=xd*xsc;
*var_y=yd*ysc;
*var_d=sqrt(xd*xd+yd*yd)*divmax_d;
*var_r=atan2(yd,xd) + M_PI*0.5;
executeCode(codehandle[0],visdata);
int tmp1,tmp2;
if (!__rectcoords)
{
*var_d *= max_screen_d;
*var_r -= M_PI*0.5;
tmp1=(int) (dw2 + cos(*var_r) * *var_d);
tmp2=(int) (dh2 + sin(*var_r) * *var_d);
}
else
{
tmp1=(int) ((*var_x+1.0)*dw2);
tmp2=(int) ((*var_y+1.0)*dh2);
}
if (!__wrap)
{
if (tmp1 < 0) tmp1=0;
if (tmp1 > w_adj) tmp1=w_adj;
if (tmp2 < 0) tmp2=0;
if (tmp2 > h_adj) tmp2=h_adj;
}
*tabptr++ = tmp1;
*tabptr++ = tmp2;
double va=*var_alpha;
if (va < 0.0) va=0.0;
else if (va > 1.0) va=1.0;
int a=(int)(va*255.0*65536.0);
*tabptr++ = a;
}
yc_pos+=yc_dpos;
}
}
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 (max_threads < 1) max_threads=1;
int start_l = ( this_thread * h ) / max_threads;
int end_l;
int ypos=0;
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 *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
if (!fbin) return;
// yay, the table is generated. now we do a fixed point
// interpolation of the whole thing and pray.
{
int *interptab=m_tab+XRES*YRES*3 + this_thread * (XRES*6+6);
int *rdtab=m_tab;
unsigned int *in=(unsigned int *)fbin;
unsigned int *blendin=(unsigned int *)framebuffer;
unsigned int *out=(unsigned int *)fbout;
int yseek=1;
int xc_dpos, yc_pos=0, yc_dpos;
xc_dpos=(w<<16)/(XRES-1);
yc_dpos=(h<<16)/(YRES-1);
int lypos=0;
int yl=end_l;
while (yl>0)
{
yc_pos+=yc_dpos;
yseek=(yc_pos>>16)-lypos;
if (!yseek)
{
#ifndef NO_MMX
__asm emms;
#endif
return;
}
lypos=yc_pos>>16;
int l=XRES;
int *stab=interptab;
int xr3=XRES*3;
while (l--)
{
int tmp1, tmp2,tmp3;
tmp1=rdtab[0];
tmp2=rdtab[1];
tmp3=rdtab[2];
stab[0]=tmp1;
stab[1]=tmp2;
stab[2]=(rdtab[xr3]-tmp1)/yseek;
stab[3]=(rdtab[xr3+1]-tmp2)/yseek;
stab[4]=tmp3;
stab[5]=(rdtab[xr3+2]-tmp3)/yseek;
rdtab+=3;
stab+=6;
}
if (yseek > yl) yseek=yl;
yl-=yseek;
if (yseek > 0) while (yseek--)
{
int d_x;
int d_y;
int d_a;
int ap;
int seek;
int *seektab=interptab;
int xp,yp;
int l=w;
int lpos=0;
int xc_pos=0;
ypos++;
{
while (l>0)
{
xc_pos+=xc_dpos;
seek=(xc_pos>>16)-lpos;
if (!seek)
{
#ifndef NO_MMX
__asm emms;
#endif
return;
}
lpos=xc_pos>>16;
xp=seektab[0];
yp=seektab[1];
ap=seektab[4];
d_a=(seektab[10]-ap)/(seek);
d_x=(seektab[6]-xp)/(seek);
d_y=(seektab[7]-yp)/(seek);
seektab[0] += seektab[2];
seektab[1] += seektab[3];
seektab[4] += seektab[5];
seektab+=6;
if (seek>l) seek=l;
l-=seek;
if (seek > 0 && ypos <= start_l)
{
blendin+=seek;
if (__nomove) in+=seek;
else out+=seek;
seek=0;
}
if (seek>0)
{
#define CHECK
//__docheck(xp,yp,m_lastw,m_lasth,d_x,d_y);
// normal loop
#define NORMAL_LOOP(Z) while ((seek--)) { Z; xp+=d_x; yp+=d_y; }
#if 0
// this would be faster, but seems like it might be less reliable:
#define WRAPPING_LOOPS(Z) \
if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp < 0) yp += h_adj; Z) \
else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp >= h_adj) yp-=h_adj; Z) \
else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp < 0) yp += h_adj; Z) \
else NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp >= h_adj) yp-=h_adj; Z)
#define CLAMPED_LOOPS(Z) \
if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp < 0) yp=0; Z) \
else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp >= h_adj) yp=h_adj-1; Z) \
else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp < 0) yp=0; Z) \
else NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp >= h_adj) yp=h_adj-1; Z)
#else // slower, more reliable loops
// wrapping loop
#define WRAPPING_LOOPS(Z) \
NORMAL_LOOP(if (xp < 0) xp += w_adj; \
else if (xp >= w_adj) xp-=w_adj; \
if (yp < 0) yp += h_adj; \
else if (yp >= h_adj) yp-=h_adj; \
Z)
#define CLAMPED_LOOPS(Z) \
NORMAL_LOOP(if (xp < 0) xp=0; \
else if (xp >= w_adj) xp=w_adj-1; \
if (yp < 0) yp=0; \
else if (yp >= h_adj) yp=h_adj-1; \
Z)
#endif
#define LOOPS(DO) \
if (__blend && __subpixel) DO(CHECK *out++=BLEND_ADJ(BLEND4_16(in+(xp>>16)+(m_wmul[yp>>16]),w,xp,yp),*blendin++,ap>>16); ap+=d_a) \
else if (__blend) DO(CHECK *out++=BLEND_ADJ(in[(xp>>16)+(m_wmul[yp>>16])],*blendin++,ap>>16); ap+=d_a) \
else if (__subpixel) DO(CHECK *out++=BLEND4_16(in+(xp>>16)+(m_wmul[yp>>16]),w,xp,yp)) \
else DO(CHECK *out++=in[(xp>>16)+(m_wmul[yp>>16])])
if (__nomove)
{
if (fbin != framebuffer) while (seek--)
{
*blendin=BLEND_ADJ(*in++,*blendin,ap>>16); ap+=d_a;
blendin++;
}
else while (seek--)
{
*blendin=BLEND_ADJ(0,*blendin,ap>>16); ap+=d_a;
blendin++;
}
}
else if (!__wrap)
{
// this might not really be necessary b/c of the clamping in the loop, but I'm sick of crashes
if (xp < 0) xp=0;
else if (xp >= w_adj) xp=w_adj-1;
if (yp < 0) yp=0;
else if (yp >= h_adj) yp=h_adj-1;
LOOPS(CLAMPED_LOOPS)
}
else // __wrap
{
xp %= w_adj;
yp %= h_adj;
if (xp < 0) xp+=w_adj;
if (yp < 0) yp+=h_adj;
if (d_x <= -w_adj) d_x=-w_adj+1;
else if (d_x >= w_adj) d_x=w_adj-1;
if (d_y <= -h_adj) d_y=-h_adj+1;
else if (d_y >= h_adj) d_y=h_adj-1;
LOOPS(WRAPPING_LOOPS)
}
} // if seek>0
}
// adjust final (rightmost elem) part of seektab
seektab[0] += seektab[2];
seektab[1] += seektab[3];
seektab[4] += seektab[5];
}
}
}
}
#ifndef NO_MMX
__asm emms;
#endif
}
C_RBASE *R_DMove(char *desc)
{
if (desc) { strcpy(desc,MOD_NAME); return NULL; }
return (C_RBASE *) new C_THISCLASS();
}
typedef struct
{
char *name;
int rect;
int wrap;
int grid1;
int grid2;
char *init;
char *point;
char *frame;
char *beat;
} presetType;
static presetType presets[]=
{
{"Random Rotate", 0, 1, 2, 2, "","r = r + dr;","","dr = (rand(100) / 100) * $PI;\r\nd = d * .95;"},
{"Random Direction", 1, 1, 2, 2, "speed=.05;dr = (rand(200) / 100) * $PI;","x = x + dx;\r\ny = y + dy;","dx = cos(dr) * speed;\r\ndy = sin(dr) * speed;","dr = (rand(200) / 100) * $PI;"},
{"In and Out", 0, 1, 2, 2, "speed=.2;c=0;","d = d * dd;","","c = c + ($PI/2);\r\ndd = 1 - (sin(c) * speed);"},
{"Unspun Kaleida", 0, 1, 33, 33, "c=200;f=0;dt=0;dl=0;beatdiv=8","r=cos(r*dr);","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = 4+(cos(dt)*2);","c=f;f=0;dl=dt"},
{"Roiling Gridley", 1, 1, 32, 32, "c=200;f=0;dt=0;dl=0;beatdiv=8","x=x+(sin(y*dx) * .03);\r\ny=y-(cos(x*dy) * .03);","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndx = 14+(cos(dt)*8);\r\ndy = 10+(sin(dt*2)*4);","c=f;f=0;dl=dt"},
{"6-Way Outswirl", 0, 0, 32, 32, "c=200;f=0;dt=0;dl=0;beatdiv=8","d=d*(1+(cos(r*6) * .05));\r\nr=r-(sin(d*dr) * .05);\r\nd = d * .98;","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = 18+(cos(dt)*12);","c=f;f=0;dl=dt"},
{"Wavy", 1, 1, 6, 6, "c=200;f=0;dx=0;dl=0;beatdiv=16;speed=.05","y = y + ((sin((x+dx) * $PI))*speed);\r\nx = x + .025","f = f + 1;\r\nt = ( (f * 2 * 3.1415) / c ) / beatdiv;\r\ndx = dl + t;","c = f;\r\nf = 0;\r\ndl = dx;"},
{"Smooth Rotoblitter", 0, 1, 2, 2, "c=200;f=0;dt=0;dl=0;beatdiv=4;speed=.15","r = r + dr;\r\nd = d * dd;","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = cos(dt)*speed*2;\r\ndd = 1 - (sin(dt)*speed);","c=f;f=0;dl=dt"},
};
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:
isstart=1;
SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
if (g_this->blend)
CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
if (g_this->subpixel)
CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
if (g_this->rectcoords)
CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
if (g_this->wrap)
CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
if (g_this->nomove)
CheckDlgButton(hwndDlg,IDC_NOMOVEMENT,BST_CHECKED);
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_CURRENT));
{
int i=0;
char txt[64];
for (i=0;i<NBUF;i++)
{
wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (int)txt);
}
}
SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, (WPARAM) g_this->buffern, 0);
SetDlgItemInt(hwndDlg,IDC_EDIT5,g_this->m_xres,FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT6,g_this->m_yres,FALSE);
isstart=0;
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_BUTTON1)
{
char text[4096];
WASABI_API_LNGSTRING_BUF(IDS_DYNAMIC_MOVEMENT,text,4096);
int titlelen = lstrlen(text)+1;
lstrcpyn(text+titlelen,GetTextResource(IDR_DYNAMIC_MOVEMENT),4095-titlelen);
compilerfunctionlist(hwndDlg,text);
}
if (LOWORD(wParam)==IDC_CHECK1)
{
g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
}
if (LOWORD(wParam)==IDC_CHECK2)
{
g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
}
if (LOWORD(wParam)==IDC_CHECK3)
{
g_this->rectcoords=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
}
if (LOWORD(wParam)==IDC_WRAP)
{
g_this->wrap=IsDlgButtonChecked(hwndDlg,IDC_WRAP)?1:0;
}
if (LOWORD(wParam)==IDC_NOMOVEMENT)
{
g_this->nomove=IsDlgButtonChecked(hwndDlg,IDC_NOMOVEMENT)?1:0;
}
// Load preset examples from the examples table.
if (LOWORD(wParam) == IDC_BUTTON4)
{
RECT r;
HMENU hMenu;
MENUITEMINFO i={sizeof(i),};
hMenu=CreatePopupMenu();
int x;
for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
{
i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
i.fType=MFT_STRING;
i.wID = x+16;
i.dwTypeData=presets[x].name;
i.cch=strlen(presets[x].name);
InsertMenuItem(hMenu,x,TRUE,&i);
}
GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON1),&r);
x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
{
SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
SetDlgItemInt(hwndDlg,IDC_EDIT5,presets[x-16].grid1,FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT6,presets[x-16].grid2,FALSE);
if (presets[x-16].rect)
{
g_this->rectcoords = 1;
CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
}
else
{
g_this->rectcoords = 0;
CheckDlgButton(hwndDlg,IDC_CHECK3,0);
}
if (presets[x-16].wrap)
{
g_this->wrap = 1;
CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
}
else
{
g_this->wrap = 0;
CheckDlgButton(hwndDlg,IDC_WRAP,0);
}
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
}
DestroyMenu(hMenu);
}
if (!isstart && HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO1) // handle clicks to combo box
g_this->buffern = SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0);
if (!isstart && HIWORD(wParam) == EN_CHANGE)
{
if (LOWORD(wParam) == IDC_EDIT5 || LOWORD(wParam) == IDC_EDIT6)
{
BOOL t;
g_this->m_xres=GetDlgItemInt(hwndDlg,IDC_EDIT5,&t,0);
g_this->m_yres=GetDlgItemInt(hwndDlg,IDC_EDIT6,&t,0);
}
if (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4)
{
EnterCriticalSection(&g_this->rcs);
g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
g_this->need_recompile=1;
if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
LeaveCriticalSection(&g_this->rcs);
}
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_DMOVE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DMove(char *desc) { return NULL; }
#endif
@@ -0,0 +1,324 @@
/*
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
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <commctrl.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_DotFountainClass
#define MOD_NAME "Render / Dot Fountain"
#define NUM_ROT_DIV 30
#define NUM_ROT_HEIGHT 256
typedef struct {
float r, dr;
float h, dh;
float ax,ay;
int c;
} FountainPoint;
class C_THISCLASS : public C_RBASE {
protected:
float r;
FountainPoint points[NUM_ROT_HEIGHT][NUM_ROT_DIV];
int color_tab[64];
public:
C_THISCLASS();
virtual ~C_THISCLASS();
virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int, int);
virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_FOUNTAIN,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int rotvel,angle;
int colors[5];
void initcolortab();
};
#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) { rotvel=GET_INT(); pos+=4; }
int x;
for (x = 0; x < 5; x ++)
{
if (len-pos >= 4) { colors[x]=GET_INT(); pos+=4; }
}
if (len-pos >= 4) { angle=GET_INT(); pos+=4; }
if (len-pos >= 4) { int rr=GET_INT(); pos+=4; r=rr/32.0f;}
initcolortab();
}
int C_THISCLASS::save_config(unsigned char *data)
{
int rr;
int pos=0;
int x;
PUT_INT(rotvel); pos+=4;
for (x = 0; x < 5; x ++)
{
PUT_INT(colors[x]); pos+=4;
}
PUT_INT(angle); pos+=4;
rr=(int)(r*32.0f);
PUT_INT(rr); pos+=4;
return pos;
}
void C_THISCLASS::initcolortab()
{
int x,r,g,b,dr,dg,db,t;
for (t=0; t < 4; t ++)
{
r=(colors[t]&255)<<16;
g=((colors[t]>>8)&255)<<16;
b=((colors[t]>>16)&255)<<16;
dr=(((colors[t+1]&255)-(colors[t]&255))<<16)/16;
dg=((((colors[t+1]>>8)&255)-((colors[t]>>8)&255))<<16)/16;
db=((((colors[t+1]>>16)&255)-((colors[t]>>16)&255))<<16)/16;
for (x = 0; x < 16; x ++)
{
color_tab[t*16+x]=(r>>16)|((g>>16)<<8)|((b>>16)<<16);
r+=dr;g+=dg;b+=db;
}
}
}
C_THISCLASS::C_THISCLASS()
{
colors[0]=RGB(24,107,28); // reverse BGR :)
colors[1]=RGB(35,10,255);
colors[2]=RGB(116,29,42);
colors[3]=RGB(217,54,144);
colors[4]=RGB(255,136,107);
initcolortab();
memset(points,0,sizeof(points));
angle=-20;
rotvel=16;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int width, int height)
{
if (isBeat&0x80000000) return 0;
int fo, p;
float matrix[16],matrix2[16];
matrixRotate(matrix,2,r);
matrixRotate(matrix2,1,(float)angle);
matrixMultiply(matrix,matrix2);
matrixTranslate(matrix2,0.0f,-20.0f,400.0f);
matrixMultiply(matrix,matrix2);
FountainPoint pb[NUM_ROT_DIV];
FountainPoint *in, *out;
memcpy(pb,&points[0],sizeof(pb));
fo = NUM_ROT_HEIGHT-2;
do // transform points and remove old ones
{
float booga = 1.3f / (fo+100);
in = &points[fo][0];
out = &points[fo+1][0];
for (p = 0; p < NUM_ROT_DIV; p ++)
{
*out = *in;
out->r += out->dr;
out->dh += 0.05f;
out->dr += booga;
out->h += out->dh;
out++;
in++;
}
} while (fo--);
out = &points[0][0];
in = pb;
{ // create new points
float a;
unsigned char *sd = (unsigned char *) visdata[1][0];
for (p = 0; p < NUM_ROT_DIV; p ++)
{
int t;
if (p >= NUM_ROT_DIV) t= (sd[576] ^ 128);
else t= (*sd ^ 128);
sd++;
t*=5;
t/=4;
t-=64;
if (isBeat) t+=128;
if (t > 255) t=255;
// t+=sd[576]^128;
// t/=2;
out->r = 1.0f;
float dr = t/200.0f;
if (dr < 0) dr = -dr;
out->h = 250;
dr += 1.0;
out->dh = -dr * (100.0f + (out->dh - in->dh)) / 100.0f * 2.8f;
t = t/4;
if (t > 63) t = 63;
out->c = color_tab[t];
a = p* 3.14159f * 2.0f / NUM_ROT_DIV;
out->ax=(float)sin(a);
out->ay=(float)cos(a);
out->dr =0.0;
out++;
in++;
}
}
float adj=width*440.0f/640.0f;
float adj2=height*440.0f/480.0f;
if (adj2 < adj) adj=adj2;
in = &points[0][0];
for (fo = 0; fo < NUM_ROT_HEIGHT; fo ++)
{
for (p = 0; p < NUM_ROT_DIV; p ++)
{
register float x, y, z;
matrixApply(matrix,in->ax*in->r,in->h,in->ay*in->r,&x,&y,&z);
z = adj / z;
if (z > 0.0000001)
{
register int ix = (int) (x * z) + width/2;
register int iy = (int) (y * z) + height/2;
if (iy >= 0 && iy < height && ix >= 0 && ix < width)
{
BLEND_LINE(framebuffer + iy*width + ix,in->c);
}
}
in++;
}
}
r += rotvel/5.0f;
if (r >= 360.0f) r -= 360.0f;
if (r < 0.0f) r += 360.0f;
return 0;
}
C_RBASE *R_DotFountain(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_COMMAND:
if (LOWORD(wParam) == IDC_BUTTON1)
{
g_this->rotvel=0;
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,50);
}
if (LOWORD(wParam) >= IDC_C1 && LOWORD(wParam) <= IDC_C5) {
GR_SelectColor(hwndDlg,&g_this->colors[IDC_C5-LOWORD(wParam)]);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
g_this->initcolortab();
}
return 0;
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID >= IDC_C1 && di->CtlID <= IDC_C5)
{
GR_DrawColoredButton(di,g_this->colors[IDC_C5-di->CtlID]);
}
}
return 0;
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,101);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->rotvel+50);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMAX,0,181);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETPOS,1,g_this->angle+90);
return 1;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->rotvel=t-50;
}
if (swnd == GetDlgItem(hwndDlg,IDC_ANGLE))
{
g_this->angle=t-90;
}
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_DOTPLANE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DotFountain(char *desc) {return NULL; }
#endif
@@ -0,0 +1,331 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include <math.h>
#include "resource.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_DotGridClass
#define MOD_NAME "Render / Dot Grid"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_GRID,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int num_colors;
int colors[16];
int color_pos;
int xp;
int yp;
int x_move;
int y_move;
int spacing;
int blend;
};
#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;
int x=0;
if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
else num_colors=0;
if (len-pos >= 4) { spacing=GET_INT(); pos+=4; }
if (len-pos >= 4) { x_move=GET_INT(); pos+=4; }
if (len-pos >= 4) { y_move=GET_INT(); pos+=4; }
if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0,x=0;
PUT_INT(num_colors); pos+=4;
while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
PUT_INT(spacing); pos+=4;
PUT_INT(x_move); pos+=4;
PUT_INT(y_move); pos+=4;
PUT_INT(blend); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
num_colors=1;
memset(colors,0,sizeof(colors));
colors[0]=RGB(255,255,255);
color_pos=0;
xp=0;
yp=0;
x_move=128;
y_move=128;
spacing=8;
blend=3;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
int x,y;
int current_color;
if (isBeat&0x80000000) return 0;
if (!num_colors) return 0;
color_pos++;
if (color_pos >= num_colors * 64) color_pos=0;
{
int p=color_pos/64;
int r=color_pos&63;
int c1,c2;
int r1,r2,r3;
c1=colors[p];
if (p+1 < num_colors)
c2=colors[p+1];
else c2=colors[0];
r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
current_color=r1|(r2<<8)|(r3<<16);
}
if (spacing<2)spacing=2;
while (yp < 0) yp+=spacing*256;
while (xp < 0) xp+=spacing*256;
int sy=(yp>>8)%spacing;
int sx=(xp>>8)%spacing;
framebuffer += sy*w;
for (y = sy; y < h; y += spacing)
{
if (blend==1)
for (x = sx; x < w; x += spacing)
framebuffer[x]=BLEND(framebuffer[x],current_color);
else if (blend == 2)
for (x = sx; x < w; x += spacing)
framebuffer[x]=BLEND_AVG(framebuffer[x],current_color);
else if (blend == 3)
for (x = sx; x < w; x += spacing)
BLEND_LINE(framebuffer+x,current_color);
else
for (x = sx; x < w; x += spacing)
framebuffer[x]=current_color;
framebuffer += w*spacing;
}
xp+=x_move;
yp+=y_move;
return 0;
}
C_RBASE *R_DotGrid(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
{
int x;
int w=di->rcItem.right-di->rcItem.left;
int l=0,nl;
for (x = 0; x < g_this->num_colors; x ++)
{
int color=g_this->colors[x];
nl = (w*(x+1))/g_this->num_colors;
color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
HPEN hPen,hOldPen;
HBRUSH hBrush,hOldBrush;
LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
hPen = (HPEN)CreatePen(PS_SOLID,0,color);
hBrush = CreateBrushIndirect(&lb);
hOldPen=(HPEN)SelectObject(di->hDC,hPen);
hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
SelectObject(di->hDC,hOldPen);
SelectObject(di->hDC,hOldBrush);
DeleteObject(hBrush);
DeleteObject(hPen);
l=nl;
}
}
}
return 0;
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,33);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->x_move/32+16);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,33);
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->y_move/32+16);
SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->spacing,FALSE);
if (g_this->blend==1)
CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
else if (g_this->blend==2)
CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
else if (g_this->blend==3)
CheckDlgButton(hwndDlg,IDC_RADIO4,BST_CHECKED);
else
CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
return 1;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->x_move=(t-16)*32;
}
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
{
g_this->y_move=(t-16)*32;
}
}
return 0;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON1:
g_this->x_move=0;
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,16);
return 0;
case IDC_BUTTON3:
g_this->y_move=0;
SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,16);
return 0;
case IDC_RADIO1:
case IDC_RADIO2:
case IDC_RADIO3:
case IDC_RADIO4:
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1)) g_this->blend=0;
else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2)) g_this->blend=1;
else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3)) g_this->blend=2;
else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO4)) g_this->blend=3;
break;
case IDC_NUMCOL:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
if (tr)
{
if (p > 16) p = 16;
g_this->num_colors=p;
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
}
break;
case IDC_EDIT1:
{
int p;
BOOL tr=FALSE;
p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
if (tr)
{
if (p < 2) p = 2;
g_this->spacing=p;
}
}
break;
case IDC_DEFCOL:
{
int wc=-1,w,h;
POINT p;
RECT r;
GetCursorPos(&p);
GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
p.x -= r.left;
p.y -= r.top;
w=r.right-r.left;
h=r.bottom-r.top;
if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
{
wc = (p.x*g_this->num_colors)/w;
}
if (wc>=0)
{
GR_SelectColor(hwndDlg,g_this->colors+wc);
InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
}
}
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_DOTGRID,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DotGrid(char *desc) { return NULL; }
#endif
@@ -0,0 +1,313 @@
/*
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
#include <windows.h>
#include <math.h>
#include <commctrl.h>
#include "resource.h"
#include "r_defs.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_DotPlaneClass
#define MOD_NAME "Render / Dot Plane"
#define NUM_WIDTH 64
class C_THISCLASS : public C_RBASE {
protected:
float r;
float atable[NUM_WIDTH*NUM_WIDTH];
float vtable[NUM_WIDTH*NUM_WIDTH];
int ctable[NUM_WIDTH*NUM_WIDTH];
int color_tab[64];
public:
C_THISCLASS();
virtual ~C_THISCLASS();
virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int, int);
virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_PLANE,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
int rotvel,angle;
int colors[5];
void initcolortab();
};
#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) { rotvel=GET_INT(); pos+=4; }
int x;
for (x = 0; x < 5; x ++)
{
if (len-pos >= 4) { colors[x]=GET_INT(); pos+=4; }
}
if (len-pos >= 4) { angle=GET_INT(); pos+=4; }
if (len-pos >= 4) { int rr=GET_INT(); pos+=4; r=rr/32.0f;}
initcolortab();
}
int C_THISCLASS::save_config(unsigned char *data)
{
int rr;
int pos=0;
int x;
PUT_INT(rotvel); pos+=4;
for (x = 0; x < 5; x ++)
{
PUT_INT(colors[x]); pos+=4;
}
PUT_INT(angle); pos+=4;
rr=(int)(r*32.0f);
PUT_INT(rr); pos+=4;
return pos;
}
void C_THISCLASS::initcolortab()
{
int x,r,g,b,dr,dg,db,t;
for (t=0; t < 4; t ++)
{
r=(colors[t]&255)<<16;
g=((colors[t]>>8)&255)<<16;
b=((colors[t]>>16)&255)<<16;
dr=(((colors[t+1]&255)-(colors[t]&255))<<16)/16;
dg=((((colors[t+1]>>8)&255)-((colors[t]>>8)&255))<<16)/16;
db=((((colors[t+1]>>16)&255)-((colors[t]>>16)&255))<<16)/16;
for (x = 0; x < 16; x ++)
{
color_tab[t*16+x]=(r>>16)|((g>>16)<<8)|((b>>16)<<16);
r+=dr;g+=dg;b+=db;
}
}
}
C_THISCLASS::C_THISCLASS()
{
colors[0]=RGB(24,107,28); // reverse BGR :)
colors[1]=RGB(35,10,255);
colors[2]=RGB(116,29,42);
colors[3]=RGB(217,54,144);
colors[4]=RGB(255,136,107);
initcolortab();
memset(atable,0,sizeof(atable));
memset(vtable,0,sizeof(vtable));
memset(ctable,0,sizeof(ctable));
angle=-20;
rotvel=16;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int width, int height)
{
if (isBeat&0x80000000) return 0;
float btable[NUM_WIDTH];
int fo, p;
float matrix[16],matrix2[16];
matrixRotate(matrix,2,r);
matrixRotate(matrix2,1,(float)angle);
matrixMultiply(matrix,matrix2);
matrixTranslate(matrix2,0.0f,-20.0f,400.0f);
matrixMultiply(matrix,matrix2);
memcpy(btable,&atable[0],sizeof(float)*NUM_WIDTH);
for (fo = 0; fo < NUM_WIDTH; fo ++)
{
float *i, *o, *v, *ov;
int *c,*oc;
int t=(NUM_WIDTH-(fo+2))*NUM_WIDTH;
i = &atable[t];
o = &atable[t+NUM_WIDTH];
v = &vtable[t];
ov = &vtable[t+NUM_WIDTH];
c = &ctable[t];
oc = &ctable[t+NUM_WIDTH];
if (fo == NUM_WIDTH-1)
{
unsigned char *sd = (unsigned char *)&visdata[0][0][0];
i = btable;
for (p = 0; p < NUM_WIDTH; p ++)
{
register int t;
t=max(sd[0],sd[1]);
t=max(t,sd[2]);
*o = (float)t;
t>>=2;
if (t > 63) t=63;
*oc++=color_tab[t];
*ov++ = (*o++ - *i++) / 90.0f;
sd+=3;
}
}
else for (p = 0; p < NUM_WIDTH; p ++)
{
*o = *i++ + *v;
if (*o < 0.0f) *o=0.0f;
*ov++ = *v++ - 0.15f*(*o++/255.0f);
*oc++ = *c++;
}
}
float adj=width*440.0f/640.0f;
float adj2=height*440.0f/480.0f;
if (adj2 < adj) adj=adj2;
for (fo = 0; fo < NUM_WIDTH; fo ++)
{
int f = (r < 90.0 || r > 270.0) ? NUM_WIDTH-fo-1 : fo;
float dw=350.0f/(float)NUM_WIDTH, w = -(NUM_WIDTH*0.5f)*dw;
float q = (f - NUM_WIDTH*0.5f)*dw;
int *ct = &ctable[f*NUM_WIDTH];
float *at = &atable[f*NUM_WIDTH];
int da=1;
if (r < 180.0)
{
da=-1;
dw=-dw;
w=-w+dw;
ct += NUM_WIDTH-1;
at += NUM_WIDTH-1;
}
for (p = 0; p < NUM_WIDTH; p ++)
{
float x, y, z;
matrixApply(matrix,w,64.0f-*at,q,&x,&y,&z);
z = adj / z;
register int ix = (int) (x * z) + (width/2);
register int iy = (int) (y * z) + (height/2);
if (iy >= 0 && iy < height && ix >= 0 && ix < width)
{
BLEND_LINE(framebuffer + iy*width + ix,*ct);
}
w+=dw;
ct+=da;
at+=da;
}
}
r += rotvel/5.0f;
if (r >= 360.0f) r -= 360.0f;
if (r < 0.0f) r += 360.0f;
return 0;
}
C_RBASE *R_DotPlane(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_COMMAND:
if (LOWORD(wParam) == IDC_BUTTON1)
{
g_this->rotvel=0;
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,50);
}
if (LOWORD(wParam) >= IDC_C1 && LOWORD(wParam) <= IDC_C5) {
GR_SelectColor(hwndDlg,&g_this->colors[IDC_C5-LOWORD(wParam)]);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
g_this->initcolortab();
}
return 0;
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
if (di->CtlID >= IDC_C1 && di->CtlID <= IDC_C5)
{
GR_DrawColoredButton(di,g_this->colors[IDC_C5-di->CtlID]);
}
}
return 0;
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,101);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->rotvel+50);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMAX,0,181);
SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETPOS,1,g_this->angle+90);
return 1;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->rotvel=t-50;
}
if (swnd == GetDlgItem(hwndDlg,IDC_ANGLE))
{
g_this->angle=t-90;
}
}
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_DOTPLANE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_DotPlane(char *desc) { return NULL; }
#endif
@@ -0,0 +1,280 @@
/*
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
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_FadeOutClass
#define MOD_NAME "Trans / Fadeout"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_FADEOUT,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
void maketab(void);
unsigned char fadtab[3][256];
int fadelen, color;
};
void C_THISCLASS::maketab(void)
{
int rseek=color&0xff;
int gseek=(color>>8)&0xff;
int bseek=(color>>16)&0xff;
int x;
for (x = 0; x < 256; x ++)
{
int r=x;
int g=x;
int b=x;
if (r <= rseek-fadelen) r+=fadelen;
else if (r >= rseek+fadelen) r-=fadelen;
else r=rseek;
if (g <= gseek-fadelen) g+=fadelen;
else if (g >= gseek+fadelen) g-=fadelen;
else g=gseek;
if (b <= bseek-fadelen) b+=fadelen;
else if (b >= bseek+fadelen) b-=fadelen;
else b=bseek;
fadtab[0][x]=r;
fadtab[1][x]=g;
fadtab[2][x]=b;
}
}
#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) { fadelen=GET_INT(); pos+=4; }
if (len-pos >= 4) { color=GET_INT(); pos+=4; }
maketab();
}
int C_THISCLASS::save_config(unsigned char *data)
{
int pos=0;
PUT_INT(fadelen); pos+=4;
PUT_INT(color); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
color=0;
fadelen=16;
maketab();
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (isBeat&0x80000000) return 0;
if (!fadelen) return 0;
timingEnter(1);
if (
#ifdef NO_MMX
1
#else
color
#endif
)
{
unsigned char *t=(unsigned char *)framebuffer;
int x=w*h;
while (x--)
{
t[0]=fadtab[0][t[0]];
t[1]=fadtab[1][t[1]];
t[2]=fadtab[2][t[2]];
t+=4;
}
}
#ifndef NO_MMX
else
{
int l=(w*h);
char fadj[8];
int x;
unsigned char *t=fadtab[0];
for (x = 0; x < 8; x ++) fadj[x]=this->fadelen;
__asm
{
mov edx, l
mov edi, framebuffer
movq mm7, [fadj]
shr edx, 3
align 16
_l1:
movq mm0, [edi]
movq mm1, [edi+8]
movq mm2, [edi+16]
psubusb mm0, mm7
movq mm3, [edi+24]
psubusb mm1, mm7
movq [edi], mm0
psubusb mm2, mm7
movq [edi+8], mm1
psubusb mm3, mm7
movq [edi+16], mm2
movq [edi+24], mm3
add edi, 8*4
dec edx
jnz _l1
mov edx, l
sub eax, eax
and edx, 7
jz _l3
sub ebx, ebx
sub ecx, ecx
mov esi, t
_l2:
mov al, [edi]
mov bl, [edi+1]
mov cl, [edi+2]
sub al, [esi+eax]
sub bl, [esi+ebx]
sub cl, [esi+ecx]
mov [edi], al
mov [edi+1], bl
mov [edi+2], cl
add edi, 4
dec edx
jnz _l2
_l3:
emms
}
}
#endif
timingLeave(1);
return 0;
}
C_RBASE *R_FadeOut(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)
{
int *a=NULL;
switch (uMsg)
{
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
switch (di->CtlID)
{
case IDC_LC:
GR_DrawColoredButton(di,g_this->color);
break;
}
}
return 0;
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,92);
SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->fadelen);
return 1;
case WM_HSCROLL:
{
HWND swnd = (HWND) lParam;
int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
{
g_this->fadelen=t;
g_this->maketab();
}
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_LC:
GR_SelectColor(hwndDlg,&g_this->color);
InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
g_this->maketab();
return 0;
}
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_FADE,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_FadeOut(char *desc) { return NULL; }
#endif
@@ -0,0 +1,279 @@
/*
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.
*/
#include <windows.h>
#include <commctrl.h>
#include "r_defs.h"
#include "resource.h"
#include "timing.h"
#include "../Agave/Language/api_language.h"
#ifndef LASER
#define C_THISCLASS C_FastBright
#define MOD_NAME "Trans / Fast Brightness"
class C_THISCLASS : public C_RBASE {
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 char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_FAST_BRIGHTNESS,desc,128):desc); }
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
virtual void load_config(unsigned char *data, int len);
virtual int save_config(unsigned char *data);
#ifdef NO_MMX
int tab[3][256];
#endif
int dir;
};
#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) // read configuration of max length "len" from data.
{
int pos=0;
dir=0;
if (len-pos >= 4) { dir=GET_INT(); pos+=4; }
}
#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
int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
{
int pos=0;
PUT_INT(dir); pos+=4;
return pos;
}
C_THISCLASS::C_THISCLASS()
{
#ifdef NO_MMX
int x;
for (x = 0; x < 128; x ++)
{
tab[0][x]=x+x;
tab[1][x]=x<<9;
tab[2][x]=x<<17;
}
for (; x < 256; x ++)
{
tab[0][x]=255;
tab[1][x]=255<<8;
tab[2][x]=255<<16;
}
#endif
dir=0;
}
C_THISCLASS::~C_THISCLASS()
{
}
int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
{
if (isBeat&0x80000000) return 0;
#ifdef NO_MMX // the non mmx x2 version really isn't any , in terms faster than normal brightness with no exclusions turned on
{
unsigned int *t=(unsigned int *)framebuffer;
int x;
unsigned int mask = 0x7F7F7F7F;
x=w*h/2;
if (dir == 0)
while (x--)
{
unsigned int v1=t[0];
unsigned int v2=t[1];
v1=tab[0][v1&0xff]|tab[1][(v1>>8)&0xff]|tab[2][(v1>>16)&0xff]|(v1&0xff000000);
v2=tab[0][v2&0xff]|tab[1][(v2>>8)&0xff]|tab[2][(v2>>16)&0xff]|(v2&0xff000000);
t[0]=v1;
t[1]=v2;
t+=2;
}
else if (dir == 1)
while (x--)
{
unsigned int v1=t[0]>>1;
unsigned int v2=t[1]>>1;
t[0]=v1&mask;
t[1]=v2&mask;
t+=2;
}
}
#else
int mask[2] =
{
0x7F7F7F7F,
0x7F7F7F7F,
};
int l=(w*h);
if (dir == 0) __asm
{
mov edx, l
mov edi, framebuffer
shr edx, 3 // 8 pixels at a time
align 16
_l1:
movq mm0, [edi]
movq mm1, [edi+8]
movq mm2, [edi+16]
paddusb mm0, mm0
movq mm3, [edi+24]
paddusb mm1, mm1
paddusb mm2, mm2
movq [edi], mm0
paddusb mm3, mm3
movq [edi+8], mm1
movq [edi+16], mm2
movq [edi+24], mm3
add edi, 32
dec edx
jnz _l1
mov edx, l
and edx, 7
shr edx, 1 // up the last 7 pixels (two at a time)
jz _l3
_l2:
movq mm3, [edi]
paddusb mm3, mm3
movq [edi], mm3
add edi, 8
dec edx
jnz _l2
_l3:
emms
}
else if (dir == 1) __asm
{
mov edx, l
movq mm7, [mask]
mov edi, framebuffer
shr edx, 3 // 8 pixels at a time
align 16
_lr1:
movq mm0, [edi]
movq mm1, [edi+8]
movq mm2, [edi+16]
psrl mm0, 1
movq mm3, [edi+24]
pand mm0, mm7
psrl mm1, 1
movq [edi], mm0
psrl mm2, 1
pand mm1, mm7
movq [edi+8], mm1
pand mm2, mm7
psrl mm3, 1
movq [edi+16], mm2
pand mm3, mm7
movq [edi+24], mm3
add edi, 32
dec edx
jnz _lr1
mov edx, l
and edx, 7
shr edx, 1 // up the last 7 pixels (two at a time)
jz _lr3
_lr2:
movq mm3, [edi]
psrl mm3, 1
pand mm3, mm7
movq [edi], mm3
add edi, 8
dec edx
jnz _lr2
_lr3:
emms
}
#endif
return 0;
}
C_RBASE *R_FastBright(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)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (g_this->dir==0) CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
else if (g_this->dir == 1) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
else CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
return 1;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_RADIO1)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
g_this->dir=0;
if (LOWORD(wParam) == IDC_RADIO2)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2))
g_this->dir=1;
if (LOWORD(wParam) == IDC_RADIO3)
if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3))
g_this->dir=2;
return 0;
}
return 0;
}
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
{
g_this = this;
return WASABI_API_CREATEDIALOG(IDD_CFG_FASTBRIGHT,hwndParent,g_DlgProc);
}
#else
C_RBASE *R_FastBright(char *desc) { return NULL; }
#endif

Some files were not shown because too many files have changed in this diff Show More