00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <float.h>
00029 #include <math.h>
00030 #include <windows.h>
00031 #include "struct.h"
00032 #include "..\common\postprocess\ximage.h"
00033 #include "local.h"
00034
00035 #include "glow.h"
00036
00037 #if __X__MIPS__
00038 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00039 #endif
00040
00041 static HINSTANCE hDLLinstance=NULL;
00042 static long version=1;
00043
00044 #include "utils.h"
00045 #include "paint.c"
00046
00047 #if __WATCOMC__
00048 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00049 #elif __BC__
00050 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00051 #else
00052 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00053 #endif
00054 switch (dwReason) {
00055 case DLL_PROCESS_ATTACH:
00056 #if __X__MIPS__
00057 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00058 #endif
00059 hDLLinstance = hDLL;
00060 break;
00061 case DLL_PROCESS_DETACH:
00062 #if __X__MIPS__
00063 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00064 #endif
00065 break;
00066 }
00067 return (int)TRUE;
00068 }
00069
00070 #if __SC__
00071 #pragma startaddress(DllMain)
00072 #endif
00073
00074 static void SetColour(unsigned char *colour, HWND parent){
00075 CHOOSECOLOR cc;
00076 static COLORREF CustColours[16]={
00077 RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00078 RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00079 RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00080 RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00081 cc.lStructSize=sizeof(CHOOSECOLOR);
00082 cc.hwndOwner=parent;
00083 cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00084 cc.lpCustColors=(LPDWORD)CustColours;
00085 cc.Flags= CC_RGBINIT;
00086 cc.lCustData=(DWORD)0;
00087 if(ChooseColor(&cc)){
00088 colour[0]=(unsigned char)GetRValue(cc.rgbResult);
00089 colour[1]=(unsigned char)GetGValue(cc.rgbResult);
00090 colour[2]=(unsigned char)GetBValue(cc.rgbResult);
00091 }
00092 }
00093
00094 static BOOL Aboundary(long i, long j, long X, long Y, fullscreenbuffer *Si){
00095 fullscreenbuffer *S;
00096 if(i <= 0 || i >= X-1 || j <= 0 || j >= Y-1)return FALSE;
00097
00098
00099
00100
00101 S=(Si + j*X + i - 1); if(S->A < 128)return TRUE;
00102 S=(Si + j*X + i + 1); if(S->A < 128)return TRUE;
00103 S=(Si + (j-1)*X + i); if(S->A < 128)return TRUE;
00104 S=(Si + (j+1)*X + i); if(S->A < 128)return TRUE;
00105 return FALSE;
00106 }
00107
00108 static void DrawAlphaBoundary(long x, long y, fullscreenbuffer *So,
00109 long X, long Y, long radius,
00110 fullscreenbuffer *Si,
00111 long skip,
00112 double I,double R, double G, double B){
00113 long i,j;
00114 double d;
00115 fullscreenbuffer *S;
00116 for(i=x-radius;i<=x+radius;i+=skip)for(j=y-radius;j<=y+radius;j+=skip){
00117 if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00118 S=(Si + j*X + i);
00119
00120 if(S->A > 127)continue;
00121 if(radius < 1)d=0.5;
00122 else{
00123 d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00124 if(d > (double)radius)continue;
00125 d=1.0 - d/(double)radius;
00126 }
00127 d=I*d;
00128 S=(So + j*X + i);
00129 S->R = (unsigned char)min(255.0,(double)S->R+R*d);
00130 S->G = (unsigned char)min(255.0,(double)S->G+G*d);
00131 S->B = (unsigned char)min(255.0,(double)S->B+B*d);
00132 }
00133 return;
00134 }
00135
00136 static BOOL boundary(long i, long j, long X, long Y,
00137 fullscreenbuffer *Si, long c1, long c2, long c3){
00138 fullscreenbuffer *S;
00139 if(i <= 0 || i >= X-1 || j <= 0 || j >= Y-1)return FALSE;
00140 S=(Si + j*X + i - 1);
00141 if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00142 S=(Si + j*X + i + 1);
00143 if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00144 S=(Si + (j-1)*X + i);
00145 if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00146 S=(Si + (j+1)*X + i);
00147 if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00148 return FALSE;
00149 }
00150
00151 static void DrawInBuffer(long x, long y, fullscreenbuffer *So,
00152 long X, long Y, long radius,
00153 fullscreenbuffer *Si, BOOL exclude,
00154 long c1, long c2, long c3,
00155 long skip,
00156 double z, float *Zb, double I,
00157 double R, double G, double B){
00158 long i,j;
00159 double d;
00160 fullscreenbuffer *S;
00161 for(i=x-radius;i<=x+radius;i+=skip)for(j=y-radius;j<=y+radius;j+=skip){
00162 if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00163 S=(Si + j*X + i);
00164 if(S->R == c1 && S->G == c2 && S->B == c3){
00165 if(exclude)continue;
00166 }
00167 else if(z > *(Zb + j*X + i))continue;
00168 if(radius < 1)d=0.5;
00169 else{
00170 d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00171 if(d > (double)radius)continue;
00172 d=1.0 - d/(double)radius;
00173 }
00174 d=I*d;
00175 S=(So + j*X + i);
00176
00177 S->R = (unsigned char)min(255.0,(double)S->R+R*d);
00178 S->G = (unsigned char)min(255.0,(double)S->G+G*d);
00179 S->B = (unsigned char)min(255.0,(double)S->B+B*d);
00180 }
00181 return;
00182 }
00183
00184 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00185 long i,j;
00186 char dummy[255];
00187 double z,scale,I,mr,fade;
00188 long radius,iradius,hot,c1,c2,c3,Xmax,Ymax,ifade;
00189 long miradius,mhot,mc1,mc2,mc3,mifade;
00190 float *Zb;
00191 fullscreenbuffer *S,*Screen,*So,*Si;
00192 BOOL bDraw=TRUE,bMorph=FALSE;
00193 sscanf(PrmList,"%s %ld %ld %ld %ld %ld %ld %ld",dummy,&version,&c1,&c2,&c3,
00194 &iradius,&hot,&ifade);
00195 if(lpXimage->Morph && lpXimage->mParameters != NULL){
00196 bMorph=TRUE; mr=lpXimage->MorphRatio;
00197 sscanf(lpXimage->mParameters,"%s %ld %ld %ld %ld %ld %ld %ld",dummy,
00198 &version,&mc1,&mc2,&mc3,&miradius,&mhot,&mifade);
00199 }
00200 if((Zb=lpXimage->Zbuffer) == NULL)return 0;
00201 Xmax=lpXimage->Xmax; Ymax=lpXimage->Ymax;
00202 if(bMorph){
00203 fade=((double)mifade + mr*((double)ifade-(double)mifade))/100.0;
00204 }
00205 else fade=(double)ifade/100.0;
00206 scale=Xmax/320.0*fade;
00207 Screen=lpXimage->Screen;
00208 So=(fullscreenbuffer *)X__Malloc(Xmax*Ymax*(long)sizeof(fullscreenbuffer));
00209 if(So == NULL){
00210 MessageBox(GetFocus(),"Memory Out",NULL,MB_OK);
00211 return 0;
00212 }
00213 memcpy(So,Screen,sizeof(fullscreenbuffer)*Xmax*Ymax);
00214 if(hot < 4){
00215 for(j=0;j<Ymax;j++)for(i=0;i<Xmax;i++){
00216 S=(Screen + j*Xmax + i);
00217 z = *(Zb + j*Xmax + i);
00218 if(z > FARAWAY - 10.0)continue;
00219 if(S->R != c1 || S->G != c2 || S->B != c3)continue;
00220 S=(So + j*Xmax + i);
00221 if(hot == 1){
00222 S->R = S->G = S->B = 250;
00223 if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00224 radius=13.0*scale;
00225 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00226 1,
00227 z,Zb,
00228 0.1,
00229 255.0,0.0,0.0);
00230 radius=8.0*scale;
00231 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00232 1,
00233 z,Zb,
00234 0.1,
00235 0.0,255.0,0.0);
00236 radius=2.0*scale;
00237 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00238 1,
00239 z,Zb,
00240 0.1,
00241 255.0,255.0,255.0);
00242 }
00243 }
00244 else if(hot == 2){
00245 S->R = S->G = 250; S->B= 128;
00246 if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00247 radius=13.0*scale;
00248 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00249 1,
00250 z,Zb,
00251 0.1,
00252 255.0,0.0,0.0);
00253 radius=4.0*scale;
00254 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00255 1,
00256 z,Zb,
00257 0.1,
00258 255.0,255.0,255.0);
00259 }
00260 }
00261 else{
00262 S->R = S->G = 188; S->B = 240;
00263 if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00264 radius=20.0*scale;
00265 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00266 1,
00267 z,Zb,
00268 0.1,
00269 48.0,48.0,255.0);
00270 radius=8.0*scale;
00271 DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00272 1,
00273 z,Zb,
00274 0.25,
00275 90.0,90.0,255.0);
00276 }
00277 }
00278 }
00279 }
00280 else{
00281 if(bMorph){
00282 I=((double)miradius + mr*((double)iradius-(double)miradius))/100.0;
00283 }
00284 else I=(double)iradius/100.0;
00285 for(j=0;j<Ymax;j++)for(i=0;i<Xmax;i++){
00286 Si=(Screen + j*Xmax + i);
00287 if(Si->A < 64)continue;
00288 S=(So + j*Xmax + i);
00289 if(Aboundary(i,j,Xmax,Ymax,Screen)){
00290 radius=13.0*scale;
00291 DrawAlphaBoundary(i,j,So,Xmax,Ymax,radius,Screen,1,
00292 0.1,
00293 255.0,0.0,0.0);
00294 radius=8.0*scale;
00295 DrawAlphaBoundary(i,j,So,Xmax,Ymax,radius,Screen,1,
00296 0.1,
00297 255.0,255.0,0.0);
00298 }
00299
00300 if(Si->A > 128){
00301 S->R = (unsigned char)min(255.0,(1.0-I)*(double)Si->R+255.0*I);
00302 S->G = (unsigned char)min(255.0,(1.0-I)*(double)Si->G+220.0*I);
00303 S->B = (unsigned char)min(255.0,(1.0-I)*(double)Si->B+0.0*I);
00304 }
00305 }
00306 }
00307 memcpy(Screen,So,sizeof(fullscreenbuffer)*Xmax*Ymax);
00308 X__Free(So);
00309 return 1;
00310 }
00311
00312
00313
00314 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00315 MessageBox(NULL,"Fog OpenGL function called","OK",MB_OK);
00316 return 1;
00317 }
00318
00319
00320 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00321
00322 static long irad=0,hot=1,c1=0,c2=255,c3=0,fade=100;
00323
00324 char * _SetExternalParameters(
00325 char *Op,
00326 HWND hWnd,
00327 long ruler,
00328 char *name,
00329 X__MEMORY_MANAGER *lpEVI
00330 ){
00331 char buffer[256];
00332 if(Op != NULL){
00333 sscanf(Op,"%s %ld %ld %ld %ld %ld %ld %ld",buffer,&version,&c1,&c2,&c3,
00334 &irad,&hot,&fade);
00335 }
00336 if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_GLOW),hWnd,
00337 (DLGPROC)DlgProc) == FALSE)return Op;
00338 if(Op != NULL)CALL_FREE(Op);
00339 sprintf(buffer,"%s %ld %ld %ld %ld %ld %ld %ld",name,version,c1,c2,c3,
00340 irad,hot,fade);
00341 if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00342 MessageBox (GetFocus(),"External effect: Out of memory","Error",
00343 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00344 return NULL;
00345 }
00346 strcpy(Op,buffer);
00347 return Op;
00348 }
00349
00350 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00351 BOOL err;
00352 char str[32];
00353 switch( msg ) {
00354 case WM_INITDIALOG:
00355 SetDlgItemInt(hwnd,DLG_GLOW_RADIUS,irad,FALSE);
00356 SetDlgItemInt(hwnd,DLG_GLOW_FADE,fade,FALSE);
00357 if (hot == 1)
00358 SendDlgItemMessage(hwnd,DLG_GLOW_HOT,BM_SETCHECK,TRUE,0);
00359 if (hot == 2)
00360 SendDlgItemMessage(hwnd,DLG_GLOW_WARM,BM_SETCHECK,TRUE,0);
00361 if (hot == 3)
00362 SendDlgItemMessage(hwnd,DLG_GLOW_COOL,BM_SETCHECK,TRUE,0);
00363 if (hot == 4)
00364 SendDlgItemMessage(hwnd,DLG_GLOW_RADIATE,BM_SETCHECK,TRUE,0);
00365 CentreDialogOnScreen(hwnd);
00366 return TRUE;
00367 case WM_PAINT:
00368 PaintBackground(hwnd);
00369 break;
00370 case WM_DRAWITEM:{
00371 LPDRAWITEMSTRUCT lpdis;
00372 HBRUSH hbr,hbrold;
00373 BYTE r,g,b;
00374 lpdis=(LPDRAWITEMSTRUCT)lparam;
00375 if(lpdis->CtlID == DLG_GLOW_COLOUR){
00376 r=(BYTE)c1; g=(BYTE)c2; b=(BYTE)c3;
00377 if(lpdis->itemState & ODS_SELECTED)
00378 InvertRect(lpdis->hDC,&(lpdis->rcItem));
00379 else{
00380 hbr=CreateSolidBrush(RGB(r,g,b));
00381 hbrold=SelectObject(lpdis->hDC,hbr);
00382 Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00383 lpdis->rcItem.right,lpdis->rcItem.bottom);
00384 SelectObject(lpdis->hDC,hbrold);
00385 DeleteObject(hbr);
00386 }
00387 }
00388 }
00389 break;
00390 case WM_COMMAND:
00391 switch(LOWORD(wparam)){
00392 case DLG_GLOW_COLOUR:{
00393 unsigned char colour[3];
00394 SetColour(colour,hwnd);
00395 c1=(long)colour[0]; c2=(long)colour[1]; c3=(long)colour[2];
00396 InvalidateRect(GetDlgItem(hwnd,DLG_GLOW_COLOUR),NULL,FALSE);
00397 }
00398 break;
00399 case IDCANCEL:
00400 EndDialog(hwnd,FALSE);
00401 return(TRUE);
00402 case IDOK:
00403 if (SendDlgItemMessage(hwnd,DLG_GLOW_RADIATE,BM_GETCHECK,0,0))
00404 hot=4;
00405 else if(SendDlgItemMessage(hwnd,DLG_GLOW_COOL,BM_GETCHECK,0,0))
00406 hot=3;
00407 else if(SendDlgItemMessage(hwnd,DLG_GLOW_WARM,BM_GETCHECK,0,0))
00408 hot=2;
00409 else
00410 hot=1;
00411 irad=GetDlgItemInt(hwnd,DLG_GLOW_RADIUS,&err,FALSE);
00412 if(irad < 0)irad=0;
00413 if(irad > 100)irad=100;
00414 fade=GetDlgItemInt(hwnd,DLG_GLOW_FADE,&err,FALSE);
00415 if(irad < 0)irad=0;
00416 EndDialog(hwnd,TRUE);
00417 return(TRUE);
00418 default:
00419 break;
00420 }
00421 break;
00422 default: break;
00423 }
00424 return FALSE;
00425 }
00426