00001
00002
00003
00004
00005
00006
00007
00008 #include <math.h>
00009 #include <windows.h>
00010 #include <commctrl.h>
00011
00012 #include "water.h"
00013
00014 #define UNIT 32767
00015
00016 #ifndef PI
00017 #define PI 3.1415926
00018 #endif
00019
00020 static HINSTANCE hDLLinstance=NULL;
00021
00022 #include "pstruct.h"
00023
00024 #include "paint.c"
00025
00026 #if __WATCOMC__
00027 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00028 #else
00029 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00030 #endif
00031 switch (dwReason) {
00032 case DLL_PROCESS_ATTACH:
00033 hDLLinstance = hDLL;
00034 break;
00035 case DLL_PROCESS_DETACH:
00036 break;
00037 }
00038 return (int)TRUE;
00039 }
00040
00041 static void norm(vector v){
00042 float l;
00043 l=1.0/sqrt(v[0]*v[0]+v[1]*v[1]);
00044 v[0]=v[0]*l; v[1]=v[1]*l;
00045 }
00046
00047 #define NVECTORS 25
00048
00049 static vector d[NVECTORS];
00050
00051 static void setup_water(long n){
00052 long i;
00053 float dir;
00054 d[0][0] = 0.0000; d[0][1] = 1.0000;
00055 srand(n);
00056
00057
00058
00059
00060 if(n > 1)for (i=0;i<n;i++){
00061
00062
00063 dir=6.283185*(float)(rand())/((float)RAND_MAX);
00064 d[i][0]=cos(dir); d[i][1]=sin(dir);
00065 }
00066 return;
00067 }
00068
00069
00070 long _RenderGlobalEffect
00071 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, vertex *Vlist){
00072 return 1;
00073 }
00074
00075 void _PreviewGlobalEffect
00076 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, Svertex *Vlist){
00077 return;
00078 }
00079
00080 long _RenderExternalEffect(char *parameters, sfxinfo *SFXinfo,
00081 vertex *v){
00082 char buffer[256];
00083 long i,j;
00084 long ndirections,
00085 n;
00086 float speed,phi,lambda,A[NVECTORS],Q,theta,arg,height,scale;
00087 lambda=0.0;
00088 for(i=0;i<3;i++){
00089 lambda = max(lambda,SFXinfo->vmax[i]-SFXinfo->vmin[i]);
00090 }
00091
00092 sscanf(parameters,"%s %ld %ld %f %f %f",buffer,&n,&ndirections,&height,&speed,&Q);
00093 ndirections=min(NVECTORS,ndirections);
00094 phi=speed*2*PI;
00095 scale=1.0/(double)ndirections;
00096 setup_water(ndirections);
00097
00098 for(i=0;i<ndirections;i++)A[i]=height*lambda*scale;
00099 for(i=0;i<SFXinfo->nvert;i++){
00100 v[i].p[2]=0.0;
00101 for(j=0;j<ndirections;j++){
00102 theta=(float)n*2.0*PI/lambda*(d[j][0]*v[i].p[0]+d[j][1]*v[i].p[1]);
00103 arg=theta-phi*SFXinfo->time;
00104 v[i].p[2] += A[j]*(1.0 - cos(arg));
00105 v[i].p[0] += Q*(lambda/2.0/PI/(float)n)*d[j][0]*sin(arg)*scale;
00106 v[i].p[1] += Q*(lambda/2.0/PI/(float)n)*d[j][1]*sin(arg)*scale;
00107 }
00108 }
00109 return 1;
00110 }
00111
00112 void _PreviewExternalEffect(char *parameters, sfxinfo *SFXinfo,
00113 Svertex *v){
00114 char buffer[256];
00115 long i,j;
00116 long ndirections,
00117 n;
00118 float speed,phi,lambda,A[NVECTORS],Q,theta,arg,height,scale;
00119 lambda=0.0;
00120 for(i=0;i<3;i++){
00121 lambda = max(lambda,SFXinfo->vmax[i]-SFXinfo->vmin[i]);
00122 }
00123 sscanf(parameters,"%s %ld %ld %f %f %f",buffer,&n,&ndirections,&height,&speed,&Q);
00124 ndirections=min(NVECTORS,ndirections);
00125 phi=speed*2*PI;
00126 scale=1.0/(double)ndirections;
00127 setup_water(ndirections);
00128 for(i=0;i<ndirections;i++)A[i]=height*lambda*scale;
00129 for(i=0;i<SFXinfo->nvert;i++){
00130 v[i][2]=0.0;
00131 for(j=0;j<ndirections;j++){
00132 theta=(float)n*2.0*PI/lambda*(d[j][0]*v[i][0]+d[j][1]*v[i][1]);
00133 arg=theta-phi*SFXinfo->time;
00134 v[i][2] += A[j]*(1.0 - cos(arg));
00135 v[i][0] += Q*(lambda/2.0/PI/(float)n)*d[j][0]*sin(arg)*scale;
00136 v[i][1] += Q*(lambda/2.0/PI/(float)n)*d[j][1]*sin(arg)*scale;
00137 }
00138 }
00139 return;
00140 }
00141
00142 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00143
00144 static int dlg_n=5,dlg_nwaves=1;
00145 static float dlg_A=0.05,dlg_speed=1.0,dlg_Q=0.8;
00146
00147 char * _SetExternalParameters(
00148 char *Op,
00149 HWND hWnd,
00150 long ruler,
00151 char *name,
00152 X__MEMORY_MANAGER *lpEVI
00153 ){
00154 char buffer[256];
00155 if(Op != NULL){
00156
00157 sscanf(Op,"%s %ld %ld %f %f %f",buffer,&dlg_n,&dlg_nwaves,&dlg_A,&dlg_speed,&dlg_Q);
00158 }
00159 if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_WATER),hWnd,
00160 (DLGPROC)DlgProc) == FALSE)return Op;
00161 if(Op != NULL)CALL_FREE(Op);
00162 sprintf(buffer,"%s %ld %ld %f %f %f",name,dlg_n,dlg_nwaves,dlg_A,dlg_speed,dlg_Q);
00163 if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00164 MessageBox (GetFocus(),"External effect: Out of memory","Error",
00165 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00166 return NULL;
00167 }
00168 strcpy(Op,buffer);
00169
00170 return Op;
00171 }
00172
00173 BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wparam,LPARAM lparam){
00174 char str[16];
00175 float f;
00176 switch( msg ) {
00177 case WM_INITDIALOG:
00178 LoadAnimatedClip(hDlg);
00179 CentreDialogOnScreen(hDlg);
00180 SetDlgItemInt(hDlg,DLG_N,dlg_n,FALSE);
00181 SetDlgItemInt(hDlg,DLG_NWAVES,dlg_nwaves,FALSE);
00182 sprintf(str,"%.0f",dlg_A*2000); SetDlgItemText(hDlg,DLG_A,str);
00183 sprintf(str,"%.0f",dlg_Q*100); SetDlgItemText(hDlg,DLG_Q,str);
00184 sprintf(str,"%.2f",dlg_speed); SetDlgItemText(hDlg,DLG_SPEED,str);
00185 return TRUE;
00186 case WM_PAINT:
00187 PaintBackground(hDlg);
00188 break;
00189 case WM_SYSCOMMAND:
00190 switch(LOWORD(wparam & 0xfff0)){
00191 case SC_CLOSE:
00192 EndDialog(hDlg,FALSE);
00193 return(TRUE);
00194 default:
00195 break;
00196 }
00197 break;
00198 case WM_COMMAND:
00199 switch(LOWORD(wparam)){
00200 case IDOK:
00201 if(GetDlgItemText(hDlg,DLG_N,str,12) != 0)sscanf(str,"%ld",&dlg_n);
00202 if(dlg_n < 1)dlg_n=1;
00203 if(GetDlgItemText(hDlg,DLG_NWAVES,str,12) != 0)sscanf(str,"%ld",&dlg_nwaves);
00204 if(dlg_nwaves < 1)dlg_nwaves=1;
00205 if(dlg_nwaves > NVECTORS)dlg_nwaves=NVECTORS;
00206 if(GetDlgItemText(hDlg,DLG_A,str,12) != 0){
00207 sscanf(str,"%f",&f);
00208 dlg_A = f/2000.0;
00209 }
00210 if(GetDlgItemText(hDlg,DLG_Q,str,12) != 0){
00211 sscanf(str,"%f",&f);
00212 dlg_Q = f/100.0;
00213 }
00214 if(GetDlgItemText(hDlg,DLG_SPEED,str,12) != 0){
00215 sscanf(str,"%f",&f);
00216 dlg_speed = f;
00217 }
00218 EndDialog(hDlg,TRUE);
00219 return(TRUE);
00220 case IDCANCEL:
00221 EndDialog(hDlg,FALSE);
00222 return(TRUE);
00223 default:
00224 break;
00225 }
00226 break;
00227 default: break;
00228 }
00229 return FALSE;
00230 }