r_dmove.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /*
  2. LICENSE
  3. -------
  4. Copyright 2005 Nullsoft, Inc.
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice,
  9. this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice,
  11. this list of conditions and the following disclaimer in the documentation
  12. and/or other materials provided with the distribution.
  13. * Neither the name of Nullsoft nor the names of its contributors may be used to
  14. endorse or promote products derived from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  16. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  21. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  22. OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #define M_PI 3.14159265358979323846
  25. #include <windows.h>
  26. #include <commctrl.h>
  27. #include <math.h>
  28. #include "r_defs.h"
  29. #include "resource.h"
  30. #include "avs_eelif.h"
  31. #include "r_list.h"
  32. #include "timing.h"
  33. #include "../Agave/Language/api_language.h"
  34. #if 0
  35. static void __docheck(int xp, int yp, int m_lastw, int m_lasth, int d_x, int d_y)
  36. {
  37. xp >>= 16;
  38. yp >>= 16;
  39. if (xp < 0 || xp >= m_lastw || yp < 0 || yp >= m_lasth)
  40. {
  41. char buf[512];
  42. wsprintf(buf,"@ %d,%d on %d,%d (dx,dy=%d,%d)\n",xp,yp,m_lastw,m_lasth,d_x,d_y);
  43. OutputDebugString(buf);
  44. }
  45. }
  46. #endif
  47. #ifndef LASER
  48. #define C_THISCLASS C_DMoveClass
  49. #define MOD_NAME "Trans / Dynamic Movement"
  50. class C_THISCLASS : public C_RBASE2 {
  51. protected:
  52. public:
  53. C_THISCLASS();
  54. virtual ~C_THISCLASS();
  55. virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
  56. virtual int smp_getflags() { return 1; }
  57. virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
  58. 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);
  59. 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
  60. virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_MOVEMENT,desc,128):desc); }
  61. virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
  62. virtual void load_config(unsigned char *data, int len);
  63. virtual int save_config(unsigned char *data);
  64. RString effect_exp[4];
  65. int m_lastw,m_lasth;
  66. int m_lastxres, m_lastyres, m_xres, m_yres;
  67. int *m_wmul;
  68. int *m_tab;
  69. NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
  70. double *var_d, *var_b, *var_r, *var_x, *var_y, *var_w, *var_h, *var_alpha;
  71. int inited;
  72. NSEEL_CODEHANDLE codehandle[4];
  73. int need_recompile;
  74. int buffern;
  75. int subpixel,rectcoords,blend,wrap, nomove;
  76. CRITICAL_SECTION rcs;
  77. // smp stuff
  78. int __subpixel,__rectcoords,__blend,__wrap, __nomove;
  79. int w_adj;
  80. int h_adj;
  81. int XRES;
  82. int YRES;
  83. };
  84. #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
  85. #define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
  86. void C_THISCLASS::load_config(unsigned char *data, int len)
  87. {
  88. int pos=0;
  89. if (data[pos] == 1)
  90. {
  91. pos++;
  92. load_string(effect_exp[0],data,pos,len);
  93. load_string(effect_exp[1],data,pos,len);
  94. load_string(effect_exp[2],data,pos,len);
  95. load_string(effect_exp[3],data,pos,len);
  96. }
  97. else
  98. {
  99. char buf[1025];
  100. if (len-pos >= 1024)
  101. {
  102. memcpy(buf,data+pos,1024);
  103. pos+=1024;
  104. buf[1024]=0;
  105. effect_exp[3].assign(buf+768);
  106. buf[768]=0;
  107. effect_exp[2].assign(buf+512);
  108. buf[512]=0;
  109. effect_exp[1].assign(buf+256);
  110. buf[256]=0;
  111. effect_exp[0].assign(buf);
  112. }
  113. }
  114. if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
  115. if (len-pos >= 4) { rectcoords=GET_INT(); pos+=4; }
  116. if (len-pos >= 4) { m_xres=GET_INT(); pos+=4; }
  117. if (len-pos >= 4) { m_yres=GET_INT(); pos+=4; }
  118. if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
  119. if (len-pos >= 4) { wrap=GET_INT(); pos+=4; }
  120. if (len-pos >= 4) { buffern=GET_INT(); pos+=4; }
  121. else buffern=0;
  122. if (len-pos >= 4) { nomove=GET_INT(); pos+=4; }
  123. else nomove=0;
  124. }
  125. int C_THISCLASS::save_config(unsigned char *data)
  126. {
  127. int pos=0;
  128. data[pos++]=1;
  129. save_string(data,pos,effect_exp[0]);
  130. save_string(data,pos,effect_exp[1]);
  131. save_string(data,pos,effect_exp[2]);
  132. save_string(data,pos,effect_exp[3]);
  133. PUT_INT(subpixel); pos+=4;
  134. PUT_INT(rectcoords); pos+=4;
  135. PUT_INT(m_xres); pos+=4;
  136. PUT_INT(m_yres); pos+=4;
  137. PUT_INT(blend); pos+=4;
  138. PUT_INT(wrap); pos+=4;
  139. PUT_INT(buffern); pos+=4;
  140. PUT_INT(nomove); pos+=4;
  141. return pos;
  142. }
  143. C_THISCLASS::C_THISCLASS()
  144. {
  145. AVS_EEL_INITINST();
  146. InitializeCriticalSection(&rcs);
  147. need_recompile=1;
  148. memset(codehandle,0,sizeof(codehandle));
  149. m_lasth=m_lastw=0;
  150. m_wmul=0;
  151. m_tab=0;
  152. effect_exp[0].assign("");
  153. effect_exp[1].assign("");
  154. effect_exp[2].assign("");
  155. effect_exp[3].assign("");
  156. m_lastxres=m_lastyres=0;
  157. m_xres=16;
  158. m_yres=16;
  159. var_b=0;
  160. subpixel=1;
  161. rectcoords=0;
  162. blend=0;
  163. wrap=0;
  164. buffern=0;
  165. nomove=0;
  166. }
  167. C_THISCLASS::~C_THISCLASS()
  168. {
  169. int x;
  170. for (x = 0; x < 4; x ++)
  171. {
  172. freeCode(codehandle[x]);
  173. codehandle[x]=0;
  174. }
  175. AVS_EEL_QUITINST();
  176. if (m_wmul) GlobalFree(m_wmul);
  177. if (m_tab) GlobalFree(m_tab);
  178. m_tab=0;
  179. m_wmul=0;
  180. DeleteCriticalSection(&rcs);
  181. }
  182. int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
  183. {
  184. smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
  185. if (isBeat & 0x80000000) return 0;
  186. smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
  187. return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
  188. }
  189. 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
  190. {
  191. return !__nomove;
  192. }
  193. int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
  194. {
  195. __subpixel=subpixel;
  196. __rectcoords=rectcoords;
  197. __blend=blend;
  198. __wrap=wrap;
  199. __nomove=nomove;
  200. w_adj=(w-2)<<16;
  201. h_adj=(h-2)<<16;
  202. XRES=m_xres+1;
  203. YRES=m_yres+1;
  204. if (XRES < 2) XRES=2;
  205. if (XRES > 256) XRES=256;
  206. if (YRES < 2) YRES=2;
  207. if (YRES > 256) YRES=256;
  208. if (m_lasth != h || m_lastw != w || !m_tab || !m_wmul ||
  209. m_lastxres != XRES || m_lastyres != YRES)
  210. {
  211. int y;
  212. m_lastxres = XRES;
  213. m_lastyres = YRES;
  214. m_lastw=w;
  215. m_lasth=h;
  216. if (m_wmul) GlobalFree(m_wmul);
  217. m_wmul=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
  218. for (y = 0; y < h; y ++) m_wmul[y]=y*w;
  219. if (m_tab) GlobalFree(m_tab);
  220. m_tab=(int*)GlobalAlloc(GMEM_FIXED,(XRES*YRES*3 + (XRES*6 + 6)*MAX_SMP_THREADS)*sizeof(int));
  221. }
  222. if (!__subpixel)
  223. {
  224. w_adj=(w-1)<<16;
  225. h_adj=(h-1)<<16;
  226. }
  227. if (need_recompile)
  228. {
  229. int x;
  230. int err=0;
  231. EnterCriticalSection(&rcs);
  232. if (!var_b || g_reset_vars_on_recompile)
  233. {
  234. clearVars();
  235. var_d = registerVar("d");
  236. var_b = registerVar("b");
  237. var_r = registerVar("r");
  238. var_x = registerVar("x");
  239. var_y = registerVar("y");
  240. var_w = registerVar("w");
  241. var_h = registerVar("h");
  242. var_alpha = registerVar("alpha");
  243. inited=0;
  244. }
  245. need_recompile=0;
  246. for (x = 0; x < 4; x ++)
  247. {
  248. freeCode(codehandle[x]);
  249. codehandle[x]=compileCode(effect_exp[x].get());
  250. }
  251. LeaveCriticalSection(&rcs);
  252. }
  253. if (isBeat&0x80000000) return 0;
  254. int *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
  255. if (!fbin) return 0;
  256. *var_w=(double)w;
  257. *var_h=(double)h;
  258. *var_b=isBeat?1.0:0.0;
  259. *var_alpha=0.5;
  260. if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
  261. executeCode(codehandle[1],visdata);
  262. if (isBeat) executeCode(codehandle[2],visdata);
  263. {
  264. int x;
  265. int y;
  266. int *tabptr=m_tab;
  267. double xsc=2.0/w,ysc=2.0/h;
  268. double dw2=((double)w*32768.0);
  269. double dh2=((double)h*32768.0);
  270. double max_screen_d=sqrt((double)(w*w+h*h))*0.5;
  271. double divmax_d=1.0/max_screen_d;
  272. max_screen_d *= 65536.0;
  273. int yc_pos, yc_dpos, xc_pos, xc_dpos;
  274. yc_pos=0;
  275. xc_dpos = (w<<16)/(XRES-1);
  276. yc_dpos = (h<<16)/(YRES-1);
  277. for (y = 0; y < YRES; y ++)
  278. {
  279. xc_pos=0;
  280. for (x = 0; x < XRES; x ++)
  281. {
  282. double xd,yd;
  283. xd=((double)xc_pos-dw2)*(1.0/65536.0);
  284. yd=((double)yc_pos-dh2)*(1.0/65536.0);
  285. xc_pos+=xc_dpos;
  286. *var_x=xd*xsc;
  287. *var_y=yd*ysc;
  288. *var_d=sqrt(xd*xd+yd*yd)*divmax_d;
  289. *var_r=atan2(yd,xd) + M_PI*0.5;
  290. executeCode(codehandle[0],visdata);
  291. int tmp1,tmp2;
  292. if (!__rectcoords)
  293. {
  294. *var_d *= max_screen_d;
  295. *var_r -= M_PI*0.5;
  296. tmp1=(int) (dw2 + cos(*var_r) * *var_d);
  297. tmp2=(int) (dh2 + sin(*var_r) * *var_d);
  298. }
  299. else
  300. {
  301. tmp1=(int) ((*var_x+1.0)*dw2);
  302. tmp2=(int) ((*var_y+1.0)*dh2);
  303. }
  304. if (!__wrap)
  305. {
  306. if (tmp1 < 0) tmp1=0;
  307. if (tmp1 > w_adj) tmp1=w_adj;
  308. if (tmp2 < 0) tmp2=0;
  309. if (tmp2 > h_adj) tmp2=h_adj;
  310. }
  311. *tabptr++ = tmp1;
  312. *tabptr++ = tmp2;
  313. double va=*var_alpha;
  314. if (va < 0.0) va=0.0;
  315. else if (va > 1.0) va=1.0;
  316. int a=(int)(va*255.0*65536.0);
  317. *tabptr++ = a;
  318. }
  319. yc_pos+=yc_dpos;
  320. }
  321. }
  322. return max_threads;
  323. }
  324. 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)
  325. {
  326. if (max_threads < 1) max_threads=1;
  327. int start_l = ( this_thread * h ) / max_threads;
  328. int end_l;
  329. int ypos=0;
  330. if (this_thread >= max_threads - 1) end_l = h;
  331. else end_l = ( (this_thread+1) * h ) / max_threads;
  332. int outh=end_l-start_l;
  333. if (outh<1) return;
  334. int *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
  335. if (!fbin) return;
  336. // yay, the table is generated. now we do a fixed point
  337. // interpolation of the whole thing and pray.
  338. {
  339. int *interptab=m_tab+XRES*YRES*3 + this_thread * (XRES*6+6);
  340. int *rdtab=m_tab;
  341. unsigned int *in=(unsigned int *)fbin;
  342. unsigned int *blendin=(unsigned int *)framebuffer;
  343. unsigned int *out=(unsigned int *)fbout;
  344. int yseek=1;
  345. int xc_dpos, yc_pos=0, yc_dpos;
  346. xc_dpos=(w<<16)/(XRES-1);
  347. yc_dpos=(h<<16)/(YRES-1);
  348. int lypos=0;
  349. int yl=end_l;
  350. while (yl>0)
  351. {
  352. yc_pos+=yc_dpos;
  353. yseek=(yc_pos>>16)-lypos;
  354. if (!yseek)
  355. {
  356. #ifndef NO_MMX
  357. __asm emms;
  358. #endif
  359. return;
  360. }
  361. lypos=yc_pos>>16;
  362. int l=XRES;
  363. int *stab=interptab;
  364. int xr3=XRES*3;
  365. while (l--)
  366. {
  367. int tmp1, tmp2,tmp3;
  368. tmp1=rdtab[0];
  369. tmp2=rdtab[1];
  370. tmp3=rdtab[2];
  371. stab[0]=tmp1;
  372. stab[1]=tmp2;
  373. stab[2]=(rdtab[xr3]-tmp1)/yseek;
  374. stab[3]=(rdtab[xr3+1]-tmp2)/yseek;
  375. stab[4]=tmp3;
  376. stab[5]=(rdtab[xr3+2]-tmp3)/yseek;
  377. rdtab+=3;
  378. stab+=6;
  379. }
  380. if (yseek > yl) yseek=yl;
  381. yl-=yseek;
  382. if (yseek > 0) while (yseek--)
  383. {
  384. int d_x;
  385. int d_y;
  386. int d_a;
  387. int ap;
  388. int seek;
  389. int *seektab=interptab;
  390. int xp,yp;
  391. int l=w;
  392. int lpos=0;
  393. int xc_pos=0;
  394. ypos++;
  395. {
  396. while (l>0)
  397. {
  398. xc_pos+=xc_dpos;
  399. seek=(xc_pos>>16)-lpos;
  400. if (!seek)
  401. {
  402. #ifndef NO_MMX
  403. __asm emms;
  404. #endif
  405. return;
  406. }
  407. lpos=xc_pos>>16;
  408. xp=seektab[0];
  409. yp=seektab[1];
  410. ap=seektab[4];
  411. d_a=(seektab[10]-ap)/(seek);
  412. d_x=(seektab[6]-xp)/(seek);
  413. d_y=(seektab[7]-yp)/(seek);
  414. seektab[0] += seektab[2];
  415. seektab[1] += seektab[3];
  416. seektab[4] += seektab[5];
  417. seektab+=6;
  418. if (seek>l) seek=l;
  419. l-=seek;
  420. if (seek > 0 && ypos <= start_l)
  421. {
  422. blendin+=seek;
  423. if (__nomove) in+=seek;
  424. else out+=seek;
  425. seek=0;
  426. }
  427. if (seek>0)
  428. {
  429. #define CHECK
  430. //__docheck(xp,yp,m_lastw,m_lasth,d_x,d_y);
  431. // normal loop
  432. #define NORMAL_LOOP(Z) while ((seek--)) { Z; xp+=d_x; yp+=d_y; }
  433. #if 0
  434. // this would be faster, but seems like it might be less reliable:
  435. #define WRAPPING_LOOPS(Z) \
  436. if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp < 0) yp += h_adj; Z) \
  437. else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp >= h_adj) yp-=h_adj; Z) \
  438. else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp < 0) yp += h_adj; Z) \
  439. else NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp >= h_adj) yp-=h_adj; Z)
  440. #define CLAMPED_LOOPS(Z) \
  441. if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp < 0) yp=0; Z) \
  442. else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp >= h_adj) yp=h_adj-1; Z) \
  443. else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp < 0) yp=0; Z) \
  444. else NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp >= h_adj) yp=h_adj-1; Z)
  445. #else // slower, more reliable loops
  446. // wrapping loop
  447. #define WRAPPING_LOOPS(Z) \
  448. NORMAL_LOOP(if (xp < 0) xp += w_adj; \
  449. else if (xp >= w_adj) xp-=w_adj; \
  450. if (yp < 0) yp += h_adj; \
  451. else if (yp >= h_adj) yp-=h_adj; \
  452. Z)
  453. #define CLAMPED_LOOPS(Z) \
  454. NORMAL_LOOP(if (xp < 0) xp=0; \
  455. else if (xp >= w_adj) xp=w_adj-1; \
  456. if (yp < 0) yp=0; \
  457. else if (yp >= h_adj) yp=h_adj-1; \
  458. Z)
  459. #endif
  460. #define LOOPS(DO) \
  461. 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) \
  462. else if (__blend) DO(CHECK *out++=BLEND_ADJ(in[(xp>>16)+(m_wmul[yp>>16])],*blendin++,ap>>16); ap+=d_a) \
  463. else if (__subpixel) DO(CHECK *out++=BLEND4_16(in+(xp>>16)+(m_wmul[yp>>16]),w,xp,yp)) \
  464. else DO(CHECK *out++=in[(xp>>16)+(m_wmul[yp>>16])])
  465. if (__nomove)
  466. {
  467. if (fbin != framebuffer) while (seek--)
  468. {
  469. *blendin=BLEND_ADJ(*in++,*blendin,ap>>16); ap+=d_a;
  470. blendin++;
  471. }
  472. else while (seek--)
  473. {
  474. *blendin=BLEND_ADJ(0,*blendin,ap>>16); ap+=d_a;
  475. blendin++;
  476. }
  477. }
  478. else if (!__wrap)
  479. {
  480. // this might not really be necessary b/c of the clamping in the loop, but I'm sick of crashes
  481. if (xp < 0) xp=0;
  482. else if (xp >= w_adj) xp=w_adj-1;
  483. if (yp < 0) yp=0;
  484. else if (yp >= h_adj) yp=h_adj-1;
  485. LOOPS(CLAMPED_LOOPS)
  486. }
  487. else // __wrap
  488. {
  489. xp %= w_adj;
  490. yp %= h_adj;
  491. if (xp < 0) xp+=w_adj;
  492. if (yp < 0) yp+=h_adj;
  493. if (d_x <= -w_adj) d_x=-w_adj+1;
  494. else if (d_x >= w_adj) d_x=w_adj-1;
  495. if (d_y <= -h_adj) d_y=-h_adj+1;
  496. else if (d_y >= h_adj) d_y=h_adj-1;
  497. LOOPS(WRAPPING_LOOPS)
  498. }
  499. } // if seek>0
  500. }
  501. // adjust final (rightmost elem) part of seektab
  502. seektab[0] += seektab[2];
  503. seektab[1] += seektab[3];
  504. seektab[4] += seektab[5];
  505. }
  506. }
  507. }
  508. }
  509. #ifndef NO_MMX
  510. __asm emms;
  511. #endif
  512. }
  513. C_RBASE *R_DMove(char *desc)
  514. {
  515. if (desc) { strcpy(desc,MOD_NAME); return NULL; }
  516. return (C_RBASE *) new C_THISCLASS();
  517. }
  518. typedef struct
  519. {
  520. char *name;
  521. int rect;
  522. int wrap;
  523. int grid1;
  524. int grid2;
  525. char *init;
  526. char *point;
  527. char *frame;
  528. char *beat;
  529. } presetType;
  530. static presetType presets[]=
  531. {
  532. {"Random Rotate", 0, 1, 2, 2, "","r = r + dr;","","dr = (rand(100) / 100) * $PI;\r\nd = d * .95;"},
  533. {"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;"},
  534. {"In and Out", 0, 1, 2, 2, "speed=.2;c=0;","d = d * dd;","","c = c + ($PI/2);\r\ndd = 1 - (sin(c) * speed);"},
  535. {"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"},
  536. {"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"},
  537. {"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"},
  538. {"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;"},
  539. {"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"},
  540. };
  541. static C_THISCLASS *g_this;
  542. static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  543. {
  544. static int isstart;
  545. switch (uMsg)
  546. {
  547. case WM_INITDIALOG:
  548. isstart=1;
  549. SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
  550. SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
  551. SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
  552. SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
  553. if (g_this->blend)
  554. CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
  555. if (g_this->subpixel)
  556. CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
  557. if (g_this->rectcoords)
  558. CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
  559. if (g_this->wrap)
  560. CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
  561. if (g_this->nomove)
  562. CheckDlgButton(hwndDlg,IDC_NOMOVEMENT,BST_CHECKED);
  563. SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_CURRENT));
  564. {
  565. int i=0;
  566. char txt[64];
  567. for (i=0;i<NBUF;i++)
  568. {
  569. wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
  570. SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (int)txt);
  571. }
  572. }
  573. SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, (WPARAM) g_this->buffern, 0);
  574. SetDlgItemInt(hwndDlg,IDC_EDIT5,g_this->m_xres,FALSE);
  575. SetDlgItemInt(hwndDlg,IDC_EDIT6,g_this->m_yres,FALSE);
  576. isstart=0;
  577. return 1;
  578. case WM_COMMAND:
  579. if (LOWORD(wParam) == IDC_BUTTON1)
  580. {
  581. char text[4096];
  582. WASABI_API_LNGSTRING_BUF(IDS_DYNAMIC_MOVEMENT,text,4096);
  583. int titlelen = lstrlen(text)+1;
  584. lstrcpyn(text+titlelen,GetTextResource(IDR_DYNAMIC_MOVEMENT),4095-titlelen);
  585. compilerfunctionlist(hwndDlg,text);
  586. }
  587. if (LOWORD(wParam)==IDC_CHECK1)
  588. {
  589. g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
  590. }
  591. if (LOWORD(wParam)==IDC_CHECK2)
  592. {
  593. g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
  594. }
  595. if (LOWORD(wParam)==IDC_CHECK3)
  596. {
  597. g_this->rectcoords=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
  598. }
  599. if (LOWORD(wParam)==IDC_WRAP)
  600. {
  601. g_this->wrap=IsDlgButtonChecked(hwndDlg,IDC_WRAP)?1:0;
  602. }
  603. if (LOWORD(wParam)==IDC_NOMOVEMENT)
  604. {
  605. g_this->nomove=IsDlgButtonChecked(hwndDlg,IDC_NOMOVEMENT)?1:0;
  606. }
  607. // Load preset examples from the examples table.
  608. if (LOWORD(wParam) == IDC_BUTTON4)
  609. {
  610. RECT r;
  611. HMENU hMenu;
  612. MENUITEMINFO i={sizeof(i),};
  613. hMenu=CreatePopupMenu();
  614. int x;
  615. for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
  616. {
  617. i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
  618. i.fType=MFT_STRING;
  619. i.wID = x+16;
  620. i.dwTypeData=presets[x].name;
  621. i.cch=strlen(presets[x].name);
  622. InsertMenuItem(hMenu,x,TRUE,&i);
  623. }
  624. GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON1),&r);
  625. x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
  626. if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
  627. {
  628. SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
  629. SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
  630. SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
  631. SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
  632. SetDlgItemInt(hwndDlg,IDC_EDIT5,presets[x-16].grid1,FALSE);
  633. SetDlgItemInt(hwndDlg,IDC_EDIT6,presets[x-16].grid2,FALSE);
  634. if (presets[x-16].rect)
  635. {
  636. g_this->rectcoords = 1;
  637. CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
  638. }
  639. else
  640. {
  641. g_this->rectcoords = 0;
  642. CheckDlgButton(hwndDlg,IDC_CHECK3,0);
  643. }
  644. if (presets[x-16].wrap)
  645. {
  646. g_this->wrap = 1;
  647. CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
  648. }
  649. else
  650. {
  651. g_this->wrap = 0;
  652. CheckDlgButton(hwndDlg,IDC_WRAP,0);
  653. }
  654. SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
  655. }
  656. DestroyMenu(hMenu);
  657. }
  658. if (!isstart && HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO1) // handle clicks to combo box
  659. g_this->buffern = SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0);
  660. if (!isstart && HIWORD(wParam) == EN_CHANGE)
  661. {
  662. if (LOWORD(wParam) == IDC_EDIT5 || LOWORD(wParam) == IDC_EDIT6)
  663. {
  664. BOOL t;
  665. g_this->m_xres=GetDlgItemInt(hwndDlg,IDC_EDIT5,&t,0);
  666. g_this->m_yres=GetDlgItemInt(hwndDlg,IDC_EDIT6,&t,0);
  667. }
  668. if (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4)
  669. {
  670. EnterCriticalSection(&g_this->rcs);
  671. g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
  672. g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
  673. g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
  674. g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
  675. g_this->need_recompile=1;
  676. if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
  677. LeaveCriticalSection(&g_this->rcs);
  678. }
  679. }
  680. return 0;
  681. }
  682. return 0;
  683. }
  684. HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
  685. {
  686. g_this = this;
  687. return WASABI_API_CREATEDIALOG(IDD_CFG_DMOVE,hwndParent,g_DlgProc);
  688. }
  689. #else
  690. C_RBASE *R_DMove(char *desc) { return NULL; }
  691. #endif