r_list.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  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. #include <windows.h>
  25. #include <stdio.h>
  26. #include <commctrl.h>
  27. #include "resource.h"
  28. #include "r_defs.h"
  29. #include "r_unkn.h"
  30. #include "r_list.h"
  31. #include "render.h"
  32. #include "undo.h"
  33. #include "avs_eelif.h"
  34. #include "../Agave/Language/api_language.h"
  35. #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
  36. #define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
  37. char *C_RenderListClass::get_desc() { static char desc[128]; return WASABI_API_LNGSTRING_BUF(isroot?IDS_MAIN:IDS_EFFECT_LIST,desc,128); }
  38. int g_config_seh=1;
  39. extern int g_config_smp_mt,g_config_smp;
  40. static char extsigstr[]="AVS 2.8+ Effect List Config";
  41. void C_RenderListClass::load_config_code(unsigned char *data, int len)
  42. {
  43. int pos=0;
  44. if (len-pos >= 4)
  45. {
  46. use_code=GET_INT(); pos+=4;
  47. load_string(effect_exp[0],data,pos,len);
  48. load_string(effect_exp[1],data,pos,len);
  49. }
  50. }
  51. void C_RenderListClass::load_config(unsigned char *data, int len)
  52. {
  53. int pos=0,ext;
  54. if (pos<len) { mode=data[pos++]; }
  55. if (mode&0x80)
  56. {
  57. mode&=~0x80;
  58. mode=mode|GET_INT(); pos+=4;
  59. }
  60. ext = get_extended_datasize()+5;
  61. if (ext > 5)
  62. {
  63. if (pos<ext) { inblendval=GET_INT(); pos+=4; }
  64. if (pos<ext) { outblendval=GET_INT(); pos+=4; }
  65. if (pos<ext) { bufferin=GET_INT(); pos+=4; }
  66. if (pos<ext) { bufferout=GET_INT(); pos+=4; }
  67. if (pos<ext) { ininvert=GET_INT(); pos+=4; }
  68. if (pos<ext) { outinvert=GET_INT(); pos+=4; }
  69. if (pos<ext-4) { beat_render=GET_INT(); pos+=4; } //BU
  70. if (pos<ext-4) { beat_render_frames=GET_INT(); pos+=4; }
  71. }
  72. use_code=0;
  73. effect_exp[0].assign("");
  74. effect_exp[1].assign("");
  75. while (pos < len)
  76. {
  77. char s[33];
  78. T_RenderListType t;
  79. int l_len;
  80. t.effect_index=GET_INT(); pos+=4;
  81. if (t.effect_index >= DLLRENDERBASE)
  82. {
  83. if (pos+32 > len) break;
  84. memcpy(s,data+pos,32);
  85. s[32]=0;
  86. t.effect_index=(int)s;
  87. pos+=32;
  88. }
  89. if (pos+4 > len) break;
  90. l_len=GET_INT(); pos+=4;
  91. if (pos+l_len > len || l_len < 0) break;
  92. if (ext>5 && t.effect_index >= DLLRENDERBASE && !memcmp(s,extsigstr,strlen(extsigstr)+1))
  93. {
  94. load_config_code(data+pos,l_len);
  95. }
  96. else
  97. {
  98. t.render=g_render_library->CreateRenderer(&t.effect_index,&t.has_rbase2);
  99. if (t.render)
  100. {
  101. t.render->load_config(data+pos,l_len);
  102. insertRender(&t,-1);
  103. }
  104. }
  105. pos+=l_len;
  106. }
  107. }
  108. int C_RenderListClass::save_config_code(unsigned char *data)
  109. {
  110. int pos=0;
  111. PUT_INT(use_code); pos+=4;
  112. save_string(data,pos,effect_exp[0]);
  113. save_string(data,pos,effect_exp[1]);
  114. return pos;
  115. }
  116. int C_RenderListClass::save_config(unsigned char *data)
  117. {
  118. return save_config_ex(data,0);
  119. }
  120. int C_RenderListClass::save_config_ex(unsigned char *data, int rootsave)
  121. {
  122. int pos=0;
  123. int x;
  124. if (!rootsave)
  125. {
  126. set_extended_datasize(36); // size of extended data + 4 cause we fucked up
  127. data[pos++]=(mode&0xff)|0x80;
  128. PUT_INT(mode); pos+=4;
  129. // extended_data
  130. PUT_INT(inblendval); pos+=4;
  131. PUT_INT(outblendval); pos+=4;
  132. PUT_INT(bufferin); pos+=4;
  133. PUT_INT(bufferout); pos+=4;
  134. PUT_INT(ininvert); pos+=4;
  135. PUT_INT(outinvert); pos+=4;
  136. PUT_INT(beat_render); pos+=4;
  137. PUT_INT(beat_render_frames); pos+=4;
  138. // end extended data
  139. }
  140. else data[pos++] = mode;
  141. if (!rootsave)
  142. {
  143. // write in our ext field
  144. PUT_INT(DLLRENDERBASE); pos+=4;
  145. char s[33];
  146. strncpy(s,extsigstr,32);
  147. memcpy(data+pos,s,32);
  148. pos+=32;
  149. int t=save_config_code(data+pos+4);
  150. PUT_INT(t);
  151. pos+=4+t;
  152. }
  153. for (x = 0; x < num_renders; x ++)
  154. {
  155. int t;
  156. int idx=renders[x].effect_index;
  157. if (idx==UNKN_ID)
  158. {
  159. C_UnknClass *r=(C_UnknClass *)renders[x].render;
  160. if (!r->idString[0]) { PUT_INT(r->id); pos+=4; }
  161. else
  162. {
  163. PUT_INT(r->id); pos+=4;
  164. memcpy(data+pos,r->idString,32);
  165. pos+=32;
  166. }
  167. }
  168. else
  169. {
  170. PUT_INT(idx); pos+=4;
  171. if (idx >= DLLRENDERBASE)
  172. {
  173. char s[33];
  174. strncpy(s,(char*)idx,32);
  175. memcpy(data+pos,s,32);
  176. pos+=32;
  177. }
  178. }
  179. t=renders[x].render->save_config(data+pos+4);
  180. PUT_INT(t);
  181. pos+=4+t;
  182. }
  183. return pos;
  184. }
  185. C_RenderListClass::C_RenderListClass(int iroot)
  186. {
  187. AVS_EEL_INITINST();
  188. isstart=0;
  189. #ifndef LASER
  190. nsaved=0;
  191. memset(nbw_save,0,sizeof(nbw_save));
  192. memset(nbw_save2,0,sizeof(nbw_save2));
  193. memset(nbh_save,0,sizeof(nbh_save));
  194. memset(nbh_save2,0,sizeof(nbh_save2));
  195. memset(nb_save,0,sizeof(nb_save));
  196. memset(nb_save2,0,sizeof(nb_save2));
  197. #endif
  198. inblendval=128;
  199. outblendval=128;
  200. ininvert=0;
  201. InitializeCriticalSection(&rcs);
  202. use_code=0;
  203. inited=0;
  204. need_recompile=1;
  205. memset(codehandle,0,sizeof(codehandle));
  206. var_beat=0;
  207. effect_exp[0].assign("");
  208. effect_exp[1].assign("");
  209. outinvert=0;
  210. bufferin=0;
  211. bufferout=0;
  212. isroot=iroot;
  213. num_renders=0;
  214. num_renders_alloc=0;
  215. renders=NULL;
  216. thisfb=NULL;
  217. l_w=l_h=0;
  218. mode=0;
  219. beat_render = 0;
  220. beat_render_frames = 1;
  221. fake_enabled = 0;
  222. #ifdef LASER
  223. if (!iroot) line_save=createLineList();
  224. else line_save=NULL;
  225. #endif
  226. }
  227. extern int g_n_buffers_w[NBUF],g_n_buffers_h[NBUF];
  228. extern void *g_n_buffers[NBUF];
  229. #ifndef LASER
  230. void C_RenderListClass::set_n_Context()
  231. {
  232. if (!isroot) return;
  233. if (nsaved) return;
  234. nsaved=1;
  235. memcpy(nbw_save2,g_n_buffers_w,sizeof(nbw_save2));
  236. memcpy(nbh_save2,g_n_buffers_h,sizeof(nbh_save2));
  237. memcpy(nb_save2,g_n_buffers,sizeof(nb_save2));
  238. memcpy(g_n_buffers_w,nbw_save,sizeof(nbw_save));
  239. memcpy(g_n_buffers_h,nbh_save,sizeof(nbh_save));
  240. memcpy(g_n_buffers,nb_save,sizeof(nb_save));
  241. }
  242. void C_RenderListClass::unset_n_Context()
  243. {
  244. if (!isroot) return;
  245. if (!nsaved) return;
  246. nsaved=0;
  247. memcpy(nbw_save,g_n_buffers_w,sizeof(nbw_save));
  248. memcpy(nbh_save,g_n_buffers_h,sizeof(nbh_save));
  249. memcpy(nb_save,g_n_buffers,sizeof(nb_save));
  250. memcpy(g_n_buffers_w,nbw_save2,sizeof(nbw_save2));
  251. memcpy(g_n_buffers_h,nbh_save2,sizeof(nbh_save2));
  252. memcpy(g_n_buffers,nb_save2,sizeof(nb_save2));
  253. }
  254. #endif
  255. void C_RenderListClass::smp_cleanupthreads()
  256. {
  257. if (smp_parms.threadTop>0)
  258. {
  259. if (smp_parms.hQuitHandle) SetEvent(smp_parms.hQuitHandle);
  260. WaitForMultipleObjects(smp_parms.threadTop,smp_parms.hThreads,TRUE,INFINITE);
  261. int x;
  262. for (x = 0; x < smp_parms.threadTop; x ++)
  263. {
  264. CloseHandle(smp_parms.hThreads[x]);
  265. CloseHandle(smp_parms.hThreadSignalsDone[x]);
  266. CloseHandle(smp_parms.hThreadSignalsStart[x]);
  267. }
  268. }
  269. if (smp_parms.hQuitHandle) CloseHandle(smp_parms.hQuitHandle);
  270. memset(&smp_parms,0,sizeof(smp_parms));
  271. }
  272. void C_RenderListClass::freeBuffers()
  273. {
  274. #ifndef LASER
  275. if (isroot)
  276. {
  277. int x;
  278. for (x = 0; x < NBUF; x ++)
  279. {
  280. if (nb_save[x]) GlobalFree(nb_save[x]);
  281. nb_save[x]=NULL;
  282. nbw_save[x]=nbh_save[x]=0;
  283. }
  284. }
  285. #endif
  286. }
  287. C_RenderListClass::~C_RenderListClass()
  288. {
  289. #ifdef LASER
  290. if (line_save) delete line_save;
  291. #endif
  292. clearRenders();
  293. // free nb_save
  294. freeBuffers();
  295. int x;
  296. for (x = 0; x < 2; x ++)
  297. {
  298. freeCode(codehandle[x]);
  299. codehandle[x]=0;
  300. }
  301. AVS_EEL_QUITINST();
  302. DeleteCriticalSection(&rcs);
  303. }
  304. static int __inline depthof(int c, int i)
  305. {
  306. int r= max(max((c & 0xFF), ((c & 0xFF00)>>8)), (c & 0xFF0000)>>16);
  307. return i ? 255 - r : r;
  308. }
  309. int C_RenderListClass::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
  310. {
  311. int is_preinit = (isBeat&0x80000000);
  312. if (isBeat && beat_render)
  313. fake_enabled = beat_render_frames;
  314. int use_enabled=enabled();
  315. int use_inblendval = inblendval;
  316. int use_outblendval = outblendval;
  317. int use_clear=clearfb();
  318. if (!isroot && use_code)
  319. {
  320. if (need_recompile)
  321. {
  322. EnterCriticalSection(&rcs);
  323. if (!var_beat || g_reset_vars_on_recompile)
  324. {
  325. clearVars();
  326. var_beat = registerVar("beat");
  327. var_alphain = registerVar("alphain");
  328. var_alphaout = registerVar("alphaout");
  329. var_enabled = registerVar("enabled");
  330. var_clear = registerVar("clear");
  331. var_w = registerVar("w");
  332. var_h = registerVar("h");
  333. inited=0;
  334. }
  335. need_recompile=0;
  336. int x;
  337. for (x = 0; x < 2; x ++)
  338. {
  339. freeCode(codehandle[x]);
  340. codehandle[x]=compileCode(effect_exp[x].get());
  341. }
  342. LeaveCriticalSection(&rcs);
  343. }
  344. *var_beat = ((isBeat&1) && !is_preinit) ?1.0:0.0;
  345. *var_enabled=use_enabled ? 1.0:0.0;
  346. *var_w=(double)w;
  347. *var_h=(double)h;
  348. *var_clear=use_clear ? 1.0:0.0;
  349. *var_alphain=use_inblendval/255.0;
  350. *var_alphaout=use_outblendval/255.0;
  351. if (codehandle[0] && !inited) { executeCode(codehandle[0],visdata); inited=1; }
  352. executeCode(codehandle[1],visdata);
  353. if (!is_preinit)
  354. {
  355. isBeat = *var_beat > 0.1 || *var_beat < -0.1;
  356. }
  357. use_inblendval = (int) (*var_alphain * 255.0);
  358. if (use_inblendval < 0) use_inblendval=0;
  359. else if (use_inblendval>255) use_inblendval=255;
  360. use_outblendval = (int) (*var_alphaout * 255.0);
  361. if (use_outblendval < 0) use_outblendval=0;
  362. else if (use_outblendval>255) use_outblendval=255;
  363. use_enabled = *var_enabled > 0.1 || *var_enabled < -0.1;
  364. use_clear = *var_clear > 0.1 || *var_clear < -0.1;
  365. // code execute
  366. }
  367. #ifndef LASER
  368. // root/replaceinout special cases
  369. if (isroot || (use_enabled && blendin()==1 && blendout()==1))
  370. #endif
  371. {
  372. int s=0,x;
  373. #ifndef LASER
  374. int line_blend_mode_save=g_line_blend_mode;
  375. if (thisfb) GlobalFree((HGLOBAL)thisfb);
  376. thisfb=NULL;
  377. if (use_clear&&(isroot||blendin()!=1))
  378. memset(framebuffer,0,w*h*sizeof(int));
  379. if (!is_preinit)
  380. {
  381. g_line_blend_mode=0;
  382. set_n_Context();
  383. }
  384. #else
  385. if (isroot || use_enabled)
  386. {
  387. void LineListSwap(C_LineListBase *item1, C_LineListBase *item2);
  388. if (!isroot)
  389. {
  390. line_save->ClearLineList();
  391. LineListSwap(line_save,g_laser_linelist);
  392. }
  393. #endif
  394. for (x = 0; x < num_renders; x ++)
  395. {
  396. int t=0;
  397. int smp_max_threads = g_config_smp ? g_config_smp_mt : 0;
  398. C_RBASE2 *rb2 = (C_RBASE2*)renders[x].render;
  399. if (renders[x].has_rbase2 && smp_max_threads > 1 && (rb2->smp_getflags()&1))
  400. {
  401. if (smp_max_threads>MAX_SMP_THREADS) smp_max_threads=MAX_SMP_THREADS;
  402. int nt=smp_max_threads;
  403. nt=rb2->smp_begin(nt,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  404. if (!is_preinit && nt>0)
  405. {
  406. if (nt>smp_max_threads)nt=smp_max_threads;
  407. // launch threads
  408. smp_Render(nt,rb2,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  409. t=rb2->smp_finish(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  410. }
  411. }
  412. else
  413. {
  414. if (g_config_seh && renders[x].effect_index != LIST_ID)
  415. {
  416. __try
  417. {
  418. t=renders[x].render->render(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  419. }
  420. __except(EXCEPTION_EXECUTE_HANDLER)
  421. {
  422. t=0;
  423. }
  424. }
  425. else
  426. {
  427. t=renders[x].render->render(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  428. }
  429. }
  430. if (t&1) s^=1;
  431. if (!is_preinit)
  432. {
  433. if (t&0x10000000) isBeat=1;
  434. if (t&0x20000000) isBeat=0;
  435. }
  436. }
  437. #ifdef LASER
  438. if (!isroot)
  439. {
  440. LineListSwap(line_save,g_laser_linelist);
  441. int us=g_laser_linelist->GetUsedLines();
  442. int n=g_laser_linelist->GetMaxLines()-us;
  443. if (line_save->GetUsedLines() < n) n=line_save->GetUsedLines();
  444. g_laser_linelist->SetLines(line_save->GetLineList(),us,n);
  445. g_laser_linelist->SetUsedLines(us+n);
  446. }
  447. }
  448. #else
  449. if (!is_preinit)
  450. {
  451. g_line_blend_mode=line_blend_mode_save;
  452. unset_n_Context();
  453. }
  454. #endif
  455. fake_enabled--;
  456. return s;
  457. }
  458. #ifndef LASER
  459. // check to see if we're enabled
  460. if (!use_enabled)
  461. {
  462. if (thisfb) GlobalFree((HGLOBAL)thisfb);
  463. thisfb=NULL;
  464. return 0;
  465. }
  466. fake_enabled--;
  467. // handle resize
  468. if (l_w != w || l_h != h || !thisfb)
  469. {
  470. extern int config_reuseonresize;
  471. int do_resize=config_reuseonresize && !!thisfb && l_w && l_h && !use_clear;
  472. int *newfb=(int*)GlobalAlloc(do_resize?GMEM_FIXED:GPTR,w*h*sizeof(int));
  473. if (newfb && do_resize)
  474. {
  475. int x,y;
  476. int dxpos=(l_w<<16)/w;
  477. int ypos=0;
  478. int dypos=(l_h<<16)/h;
  479. int *out=newfb;
  480. for (y = 0; y < h; y++)
  481. {
  482. int *p=thisfb + l_w * (ypos>>16);
  483. int xpos=0;
  484. for (x = 0; x < w; x ++)
  485. {
  486. *out++=p[xpos>>16];
  487. xpos+=dxpos;
  488. }
  489. ypos+=dypos;
  490. }
  491. }
  492. l_w=w;
  493. l_h=h;
  494. if (thisfb) GlobalFree((HGLOBAL)thisfb);
  495. thisfb=newfb;
  496. }
  497. // handle clear mode
  498. if (use_clear) memset(thisfb,0,w*h*sizeof(int));
  499. // blend parent framebuffer into current, if necessary
  500. if (!is_preinit)
  501. {
  502. int x=w*h;
  503. int *tfb=framebuffer;
  504. int *o=thisfb;
  505. set_n_Context();
  506. int use_blendin=blendin();
  507. if (use_blendin == 10 && use_inblendval >= 255)
  508. use_blendin=1;
  509. switch (use_blendin)
  510. {
  511. case 1:
  512. memcpy(o,tfb,w*h*sizeof(int));
  513. break;
  514. case 2:
  515. mmx_avgblend_block(o,tfb,x);
  516. break;
  517. case 3:
  518. while (x--)
  519. {
  520. *o=BLEND_MAX(*o,*tfb++);
  521. o++;
  522. }
  523. break;
  524. case 4:
  525. mmx_addblend_block(o,tfb,x);
  526. break;
  527. case 5:
  528. while (x--)
  529. {
  530. *o=BLEND_SUB(*o,*tfb++);
  531. o++;
  532. }
  533. break;
  534. case 6:
  535. while (x--)
  536. {
  537. *o=BLEND_SUB(*tfb++,*o);
  538. o++;
  539. }
  540. break;
  541. case 7:
  542. {
  543. int y=h/2;
  544. while (y-- > 0)
  545. {
  546. memcpy(o,tfb,w*sizeof(int));
  547. tfb+=w*2;
  548. o+=w*2;
  549. }
  550. }
  551. break;
  552. case 8:
  553. {
  554. int r=0;
  555. int y=h;
  556. while (y-- > 0)
  557. {
  558. int *out, *in;
  559. int x=w/2;
  560. out=o+r;
  561. in=tfb+r;
  562. r^=1;
  563. while (x-- > 0)
  564. {
  565. *out=*in;
  566. out+=2;
  567. in+=2;
  568. }
  569. o+=w;
  570. tfb+=w;
  571. }
  572. }
  573. break;
  574. case 9:
  575. while (x--)
  576. {
  577. *o=*o^*tfb++;
  578. o++;
  579. }
  580. break;
  581. case 10:
  582. mmx_adjblend_block(o,tfb,o,x,use_inblendval);
  583. break;
  584. case 11:
  585. mmx_mulblend_block(o,tfb,x);
  586. break;
  587. case 13:
  588. while (x--)
  589. {
  590. *o=BLEND_MIN(*o,*tfb++);
  591. o++;
  592. }
  593. break;
  594. case 12:
  595. {
  596. int *buf=(int*)getGlobalBuffer(w,h,bufferin,0);
  597. if (!buf) break;
  598. while (x--)
  599. {
  600. *o=BLEND_ADJ(*tfb++,*o, depthof(*buf, ininvert));
  601. o++;
  602. buf++;
  603. }
  604. }
  605. #ifndef NO_MMX
  606. __asm emms;
  607. #endif
  608. break;
  609. default:
  610. break;
  611. }
  612. unset_n_Context();
  613. }
  614. int s=0;
  615. int x;
  616. int line_blend_mode_save=g_line_blend_mode;
  617. if (!is_preinit) g_line_blend_mode=0;
  618. for (x = 0; x < num_renders; x ++)
  619. {
  620. int t=0;
  621. int smp_max_threads;
  622. C_RBASE2 *rb2;
  623. if (renders[x].has_rbase2 && (smp_max_threads=g_config_smp ? g_config_smp_mt : 0) > 1 && ((rb2 = (C_RBASE2*)renders[x].render)->smp_getflags()&1))
  624. {
  625. if (smp_max_threads>MAX_SMP_THREADS) smp_max_threads=MAX_SMP_THREADS;
  626. int nt=smp_max_threads;
  627. nt=rb2->smp_begin(nt,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  628. if (!is_preinit && nt>0)
  629. {
  630. if (nt>smp_max_threads)nt=smp_max_threads;
  631. // launch threads
  632. smp_Render(nt,rb2,visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
  633. t=rb2->smp_finish(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
  634. }
  635. }
  636. else if (g_config_seh && renders[x].effect_index != LIST_ID)
  637. {
  638. __try
  639. {
  640. t=renders[x].render->render(visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
  641. }
  642. __except(EXCEPTION_EXECUTE_HANDLER)
  643. {
  644. t=0;
  645. }
  646. }
  647. else
  648. {
  649. t=renders[x].render->render(visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
  650. }
  651. if (t&1) s^=1;
  652. if (!is_preinit)
  653. {
  654. if (t&0x10000000)
  655. isBeat=1;
  656. if (t&0x20000000)
  657. isBeat=0;
  658. }
  659. }
  660. if (!is_preinit) g_line_blend_mode=line_blend_mode_save;
  661. // if s==1 at this point, data we want is in fbout.
  662. if (!is_preinit)
  663. {
  664. if (s) memcpy(thisfb,fbout,w*h*sizeof(int));
  665. int *tfb=s?fbout:thisfb;
  666. int *o=framebuffer;
  667. x=w*h;
  668. set_n_Context();
  669. int use_blendout=blendout();
  670. if (use_blendout == 10 && use_outblendval >= 255)
  671. use_blendout=1;
  672. switch (use_blendout)
  673. {
  674. case 1:
  675. if (s)
  676. {
  677. unset_n_Context();
  678. return 1;
  679. }
  680. memcpy(o,tfb,x*sizeof(int));
  681. break;
  682. case 2:
  683. mmx_avgblend_block(o,tfb,x);
  684. break;
  685. case 3:
  686. while (x--)
  687. {
  688. *o=BLEND_MAX(*o,*tfb++);
  689. o++;
  690. }
  691. break;
  692. case 4:
  693. mmx_addblend_block(o,tfb,x);
  694. break;
  695. case 5:
  696. while (x--)
  697. {
  698. *o=BLEND_SUB(*o,*tfb++);
  699. o++;
  700. }
  701. break;
  702. case 6:
  703. while (x--)
  704. {
  705. *o=BLEND_SUB(*tfb++,*o);
  706. o++;
  707. }
  708. break;
  709. case 7:
  710. {
  711. int y=h/2;
  712. while (y-- > 0)
  713. {
  714. memcpy(o,tfb,w*sizeof(int));
  715. tfb+=w*2;
  716. o+=w*2;
  717. }
  718. }
  719. break;
  720. case 8:
  721. {
  722. int r=0;
  723. int y=h;
  724. while (y-- > 0)
  725. {
  726. int *out, *in;
  727. int x=w/2;
  728. out=o+r;
  729. in=tfb+r;
  730. r^=1;
  731. while (x-- > 0)
  732. {
  733. *out=*in;
  734. out+=2;
  735. in+=2;
  736. }
  737. o+=w;
  738. tfb+=w;
  739. }
  740. }
  741. break;
  742. case 9:
  743. while (x--)
  744. {
  745. *o=*o^*tfb++;
  746. o++;
  747. }
  748. break;
  749. case 10:
  750. mmx_adjblend_block(o,tfb,o,x,use_outblendval);
  751. break;
  752. case 11:
  753. mmx_mulblend_block(o,tfb,x);
  754. break;
  755. case 13:
  756. while (x--)
  757. {
  758. *o=BLEND_MIN(*o,*tfb++);
  759. o++;
  760. }
  761. break;
  762. case 12:
  763. {
  764. int *buf=(int*)getGlobalBuffer(w,h,bufferout,0);
  765. if (!buf) break;
  766. while (x--)
  767. {
  768. *o=BLEND_ADJ(*tfb++,*o, depthof(*buf, outinvert));
  769. o++;
  770. buf++;
  771. }
  772. #ifndef NO_MMX
  773. __asm emms;
  774. #endif
  775. }
  776. break;
  777. default:
  778. break;
  779. }
  780. unset_n_Context();
  781. }
  782. return 0;
  783. #endif // !LASER
  784. }
  785. int C_RenderListClass::getNumRenders(void)
  786. {
  787. return num_renders;
  788. }
  789. C_RenderListClass::T_RenderListType *C_RenderListClass::getRender(int index)
  790. {
  791. if (index >= 0 && index < num_renders) return &renders[index];
  792. return NULL;
  793. }
  794. int C_RenderListClass::findRender(T_RenderListType *r)
  795. {
  796. int idx;
  797. if (!r) return -1;
  798. for (idx=0;idx<num_renders&&renders[idx].render!=r->render; idx++);
  799. if (idx<num_renders) return idx;
  800. return -1;
  801. }
  802. int C_RenderListClass::removeRenderFrom(T_RenderListType *r, int del)
  803. {
  804. int idx;
  805. if (!r) return 1;
  806. for (idx=0;idx<num_renders&&renders[idx].render!=r->render; idx++);
  807. return removeRender(idx,del);
  808. }
  809. int C_RenderListClass::removeRender(int index, int del)
  810. {
  811. if (index >= 0 && index < num_renders)
  812. {
  813. if (del&&renders[index].render) delete renders[index].render;
  814. num_renders--;
  815. while (index<num_renders)
  816. {
  817. renders[index]=renders[index+1];
  818. index++;
  819. }
  820. if (!num_renders)
  821. {
  822. num_renders_alloc=0;
  823. if (renders) GlobalFree((HGLOBAL)renders);
  824. renders=NULL;
  825. }
  826. return 0;
  827. }
  828. return 1;
  829. }
  830. void C_RenderListClass::clearRenders(void)
  831. {
  832. int x;
  833. if (renders)
  834. {
  835. for (x = 0; x < num_renders; x ++)
  836. {
  837. delete renders[x].render;
  838. }
  839. GlobalFree((HGLOBAL)renders);
  840. }
  841. num_renders=0;
  842. num_renders_alloc=0;
  843. renders=NULL;
  844. if (thisfb) GlobalFree((HGLOBAL)thisfb);
  845. thisfb=0;
  846. }
  847. int C_RenderListClass::insertRenderBefore(T_RenderListType *r, T_RenderListType *before)
  848. {
  849. int idx;
  850. if (!before) idx=num_renders;
  851. else for (idx=0;idx<num_renders&&renders[idx].render!=before->render; idx++);
  852. return insertRender(r,idx);
  853. }
  854. int C_RenderListClass::insertRender(T_RenderListType *r, int index) // index=-1 for add
  855. {
  856. if (num_renders+1 >= num_renders_alloc || !renders)
  857. {
  858. num_renders_alloc=num_renders+16;
  859. T_RenderListType *newr=(T_RenderListType *) GlobalAlloc(GPTR,num_renders_alloc*sizeof(T_RenderListType));
  860. if (!newr) return -1;
  861. if (num_renders&&renders)
  862. {
  863. memcpy(newr,renders,num_renders*sizeof(T_RenderListType));
  864. }
  865. if (renders)
  866. {
  867. GlobalFree((HGLOBAL)renders);
  868. }
  869. renders=newr;
  870. }
  871. if (index<0 || index>=num_renders)
  872. {
  873. renders[num_renders]=*r;
  874. return num_renders++;
  875. }
  876. int x;
  877. for (x=num_renders++; x > index; x--)
  878. {
  879. renders[x]=renders[x-1];
  880. }
  881. renders[x]=*r;
  882. return x;
  883. }
  884. void C_RenderListClass::FillBufferCombo(HWND dlg, int ctl)
  885. {
  886. int i=0;
  887. char txt[64];
  888. for (i=0;i<NBUF;i++)
  889. {
  890. wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
  891. SendDlgItemMessage(dlg, ctl, CB_ADDSTRING, 0, (LPARAM)txt);
  892. }
  893. }
  894. static C_RenderListClass *g_this;
  895. int blendmodes[] =
  896. {
  897. IDS_IGNORE,
  898. IDS_REPLACE,
  899. IDS_50_50,
  900. IDS_MAXIMUM,
  901. IDS_ADDITIVE,
  902. IDS_SUBTRACTIVE_1,
  903. IDS_SUBTRACTIVE_2,
  904. IDS_EVERY_OTHER_LINE,
  905. IDS_EVERY_OTHER_PIXEL,
  906. IDS_XOR,
  907. IDS_ADJUSTABLE,
  908. IDS_MULTIPLY,
  909. IDS_BUFFER,
  910. IDS_MINIMUM,
  911. };
  912. BOOL CALLBACK C_RenderListClass::g_DlgProcRoot(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  913. {
  914. switch (uMsg)
  915. {
  916. case WM_INITDIALOG:
  917. #ifdef LASER
  918. ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK1),SW_HIDE);
  919. #endif
  920. {
  921. #ifndef LASER
  922. if (g_this->clearfb()) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
  923. #endif
  924. }
  925. return 1;
  926. case WM_COMMAND:
  927. switch (LOWORD(wParam))
  928. {
  929. case IDC_CHECK1:
  930. g_this->set_clearfb(IsDlgButtonChecked(hwndDlg,IDC_CHECK1));
  931. break;
  932. }
  933. break;
  934. }
  935. return 0;
  936. }
  937. BOOL CALLBACK C_RenderListClass::g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  938. {
  939. switch (uMsg)
  940. {
  941. case WM_INITDIALOG:
  942. #ifdef LASER
  943. ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK1),SW_HIDE);
  944. ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), SW_HIDE);
  945. ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), SW_HIDE);
  946. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), SW_HIDE);
  947. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), SW_HIDE);
  948. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), SW_HIDE);
  949. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), SW_HIDE);
  950. ShowWindow(GetDlgItem(hwndDlg, IDC_COMBO1), SW_HIDE);
  951. ShowWindow(GetDlgItem(hwndDlg, IDC_COMBO2), SW_HIDE);
  952. ShowWindow(GetDlgItem(hwndDlg, IDC_FR1), SW_HIDE);
  953. ShowWindow(GetDlgItem(hwndDlg, IDC_FR2), SW_HIDE);
  954. #endif
  955. {
  956. #ifndef LASER
  957. {
  958. int x;
  959. for (x = 0; x < sizeof(blendmodes)/sizeof(blendmodes[0]); x ++)
  960. {
  961. char blendStr[64];
  962. SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRING_BUF(blendmodes[x],blendStr,64));
  963. SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_ADDSTRING,0,(LPARAM)blendStr);
  964. }
  965. SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,(WPARAM)g_this->blendout(),0);
  966. SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_SETCURSEL,(WPARAM)g_this->blendin(),0);
  967. ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), (g_this->blendin() == 10) ? SW_NORMAL : SW_HIDE);
  968. ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), (g_this->blendout() == 10) ? SW_NORMAL : SW_HIDE);
  969. SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
  970. SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_SETPOS, TRUE, (int)(g_this->inblendval));
  971. SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
  972. SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_SETPOS, TRUE, (int)(g_this->outblendval));
  973. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
  974. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
  975. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
  976. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
  977. g_this->FillBufferCombo(hwndDlg, IDC_CBBUF1);
  978. g_this->FillBufferCombo(hwndDlg, IDC_CBBUF2);
  979. SendDlgItemMessage(hwndDlg, IDC_CBBUF1, CB_SETCURSEL, (WPARAM) g_this->bufferin, 0);
  980. SendDlgItemMessage(hwndDlg, IDC_CBBUF2, CB_SETCURSEL, (WPARAM) g_this->bufferout, 0);
  981. if (g_this->ininvert) CheckDlgButton(hwndDlg,IDC_INVERT1,BST_CHECKED);
  982. if (g_this->outinvert) CheckDlgButton(hwndDlg,IDC_INVERT2,BST_CHECKED);
  983. }
  984. if (g_this->clearfb()) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
  985. #endif
  986. g_this->isstart=1;
  987. SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[0].get());
  988. SetDlgItemText(hwndDlg,IDC_EDIT5,g_this->effect_exp[1].get());
  989. g_this->isstart=0;
  990. if (((g_this->mode&2)^2))
  991. CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
  992. if (g_this->beat_render) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
  993. else EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), FALSE);
  994. if (g_this->use_code) CheckDlgButton(hwndDlg,IDC_CHECK4,BST_CHECKED);
  995. char buf[999];
  996. wsprintf(buf, "%d", g_this->beat_render_frames);
  997. SetDlgItemText(hwndDlg,IDC_EDIT1,buf);
  998. }
  999. return 1;
  1000. case WM_COMMAND:
  1001. switch (LOWORD(wParam))
  1002. {
  1003. case IDC_EDIT4:
  1004. case IDC_EDIT5:
  1005. if (!g_this->isstart && HIWORD(wParam) == EN_CHANGE)
  1006. {
  1007. EnterCriticalSection(&g_this->rcs);
  1008. g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT4);
  1009. g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT5);
  1010. g_this->need_recompile=1;
  1011. if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
  1012. LeaveCriticalSection(&g_this->rcs);
  1013. }
  1014. break;
  1015. case IDC_COMBO1:
  1016. if (HIWORD(wParam) == CBN_SELCHANGE)
  1017. {
  1018. int r=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
  1019. if (r!=CB_ERR)
  1020. {
  1021. g_this->set_blendout(r);
  1022. ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), (r == 10) ? SW_NORMAL : SW_HIDE);
  1023. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
  1024. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
  1025. }
  1026. }
  1027. break;
  1028. case IDC_COMBO2:
  1029. if (HIWORD(wParam) == CBN_SELCHANGE)
  1030. {
  1031. int r=SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_GETCURSEL,0,0);
  1032. if (r!=CB_ERR)
  1033. {
  1034. g_this->set_blendin(r);
  1035. ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), (r == 10) ? SW_NORMAL : SW_HIDE);
  1036. ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
  1037. ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
  1038. }
  1039. }
  1040. break;
  1041. case IDC_CBBUF1:
  1042. if (HIWORD(wParam) == CBN_SELCHANGE)
  1043. g_this->bufferin = SendDlgItemMessage(hwndDlg, IDC_CBBUF1, CB_GETCURSEL, 0, 0);
  1044. break;
  1045. case IDC_CBBUF2:
  1046. if (HIWORD(wParam) == CBN_SELCHANGE)
  1047. g_this->bufferout = SendDlgItemMessage(hwndDlg, IDC_CBBUF2, CB_GETCURSEL, 0, 0);
  1048. break;
  1049. case IDC_CHECK1:
  1050. g_this->set_clearfb(IsDlgButtonChecked(hwndDlg,IDC_CHECK1));
  1051. break;
  1052. case IDC_CHECK2:
  1053. g_this->set_enabled(IsDlgButtonChecked(hwndDlg,IDC_CHECK2));
  1054. break;
  1055. case IDC_INVERT1:
  1056. g_this->ininvert = IsDlgButtonChecked(hwndDlg,IDC_INVERT1);
  1057. break;
  1058. case IDC_INVERT2:
  1059. g_this->outinvert = IsDlgButtonChecked(hwndDlg,IDC_INVERT2);
  1060. break;
  1061. case IDC_CHECK3:
  1062. g_this->beat_render = IsDlgButtonChecked(hwndDlg,IDC_CHECK3);
  1063. EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), g_this->beat_render);
  1064. break;
  1065. case IDC_CHECK4:
  1066. g_this->use_code = !!IsDlgButtonChecked(hwndDlg,IDC_CHECK4);
  1067. break;
  1068. case IDC_EDIT1:
  1069. if (HIWORD(wParam) == EN_CHANGE) {
  1070. char buf[999]="1";
  1071. GetDlgItemText(hwndDlg, IDC_EDIT1, buf, 999);
  1072. buf[998] = 0;
  1073. g_this->beat_render_frames = atoi(buf);
  1074. }
  1075. break;
  1076. case IDC_BUTTON2:
  1077. {
  1078. /* char text[4096];
  1079. WASABI_API_LNGSTRING_BUF(IDS_EFFECT_LIST,text,4096);
  1080. int titlelen = lstrlen(text)+1;
  1081. lstrcpyn(text+titlelen,GetTextResource(IDR_EFFECT_LIST),4095-titlelen);
  1082. */
  1083. char *text="Effect List\0"
  1084. "Read/write 'enabled' to get/set whether the effect list is enabled for this frame\r\n"
  1085. "Read/write 'beat' to get/set whether there is currently a beat\r\n"
  1086. "Read/write 'clear' to get/set whether to clear the framebuffer\r\n"
  1087. "If the input blend is set to adjustable, 'alphain' can be set from 0.0-1.0\r\n"
  1088. "If the output blend is set to adjustable, 'alphaout' can be set from 0.0-1.0\r\n"
  1089. "'w' and 'h' are set with the current width and height of the frame\r\n"
  1090. ;
  1091. compilerfunctionlist(hwndDlg,text);
  1092. }
  1093. break;
  1094. }
  1095. break;
  1096. case WM_NOTIFY:
  1097. if (LOWORD(wParam) == IDC_INSLIDE)
  1098. g_this->inblendval = SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_GETPOS, 0, 0);
  1099. if (LOWORD(wParam) == IDC_OUTSLIDE)
  1100. g_this->outblendval = SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_GETPOS, 0, 0);
  1101. break;
  1102. }
  1103. return 0;
  1104. }
  1105. HWND C_RenderListClass::conf(HINSTANCE hInstance, HWND hwndParent)
  1106. {
  1107. g_this = this;
  1108. return WASABI_API_CREATEDIALOG(isroot?IDD_CFG_LISTROOT:IDD_CFG_LIST,hwndParent,(WNDPROC)(isroot?g_DlgProcRoot:g_DlgProc));
  1109. // return NULL;
  1110. }
  1111. char C_RenderListClass::sig_str[] = "Nullsoft AVS Preset 0.2\x1a";
  1112. int C_RenderListClass::__SavePreset(char *filename)
  1113. {
  1114. EnterCriticalSection(&g_render_cs);
  1115. unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1124*1024);
  1116. int success=-1;
  1117. if (data)
  1118. {
  1119. int pos=0;
  1120. memcpy(data+pos,sig_str,strlen(sig_str)); pos += strlen(sig_str);
  1121. pos+=save_config_ex(data+pos,1);
  1122. if (pos < 1024*1024)
  1123. {
  1124. HANDLE fp=CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  1125. if (fp!=INVALID_HANDLE_VALUE)
  1126. {
  1127. DWORD dw;
  1128. success=0;
  1129. WriteFile(fp,data,pos,&dw,NULL);
  1130. CloseHandle(fp);
  1131. }
  1132. else success=2;
  1133. }
  1134. else success=1;
  1135. GlobalFree((HGLOBAL)data);
  1136. }
  1137. LeaveCriticalSection(&g_render_cs);
  1138. return success;
  1139. }
  1140. int C_RenderListClass::__LoadPreset(char *filename, int clear)
  1141. {
  1142. EnterCriticalSection(&g_render_cs);
  1143. unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1024*1024);
  1144. int success=1;
  1145. if (clear) clearRenders();
  1146. if (data)
  1147. {
  1148. // OutputDebugString(filename);
  1149. HANDLE fp=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  1150. if (fp!=INVALID_HANDLE_VALUE)
  1151. {
  1152. DWORD len=GetFileSize(fp,NULL);
  1153. if (len == 0xffffffff) len=0;
  1154. if (!ReadFile(fp,data,min(len,1024*1024),&len,NULL)) len=0;
  1155. CloseHandle(fp);
  1156. if (len>strlen(sig_str)+2 && !memcmp(data,sig_str,strlen(sig_str)-2) &&
  1157. data[strlen(sig_str)-2] >= '1' &&
  1158. data[strlen(sig_str)-2] <= '2' &&
  1159. data[strlen(sig_str)-1] == '\x1a')
  1160. {
  1161. load_config(data+strlen(sig_str),len-strlen(sig_str));
  1162. success=0;
  1163. }
  1164. else
  1165. {
  1166. // if (len<=strlen(sig_str)+2) MessageBox(NULL,"Error loading preset: len",filename,MB_OK);
  1167. // else MessageBox(NULL,"Error loading preset: signature",filename,MB_OK);
  1168. }
  1169. }
  1170. // else MessageBox(NULL,"Error loading preset: fopen",filename,MB_OK);
  1171. GlobalFree((HGLOBAL)data);
  1172. }
  1173. // else MessageBox(NULL,"Error loading preset: MALLOC",filename,MB_OK);
  1174. LeaveCriticalSection(&g_render_cs);
  1175. return success;
  1176. }
  1177. int C_RenderListClass::__SavePresetToUndo(C_UndoItem &item)
  1178. {
  1179. EnterCriticalSection(&g_render_cs);
  1180. unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1124*1024);
  1181. int success=-1;
  1182. if (data)
  1183. {
  1184. // Do whatever the file saving stuff did
  1185. int pos=0;
  1186. memcpy(data+pos,sig_str,strlen(sig_str)); pos += strlen(sig_str);
  1187. pos+=save_config_ex(data+pos,1);
  1188. // And then set the data into the undo object.
  1189. if (pos < 1024*1024)
  1190. {
  1191. item.set(data, pos, true); // all undo items start dirty.
  1192. }
  1193. else success=1;
  1194. GlobalFree((HGLOBAL)data);
  1195. }
  1196. LeaveCriticalSection(&g_render_cs);
  1197. return success;
  1198. }
  1199. int C_RenderListClass::__LoadPresetFromUndo(C_UndoItem &item, int clear)
  1200. {
  1201. EnterCriticalSection(&g_render_cs);
  1202. unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1024*1024);
  1203. int success=1;
  1204. if (clear) clearRenders();
  1205. if (data)
  1206. {
  1207. if (item.size() < 1024*1024)
  1208. {
  1209. // Get the data from the undo object.
  1210. DWORD len = item.size();
  1211. if (len == 0xffffffff) len=0;
  1212. memcpy(data, item.get(), item.size());
  1213. // And then do whatever the file loading stuff did.
  1214. if (!memcmp(data,sig_str,strlen(sig_str)-2) &&
  1215. data[strlen(sig_str)-2] >= '1' &&
  1216. data[strlen(sig_str)-2] <= '2' &&
  1217. data[strlen(sig_str)-1] == '\x1a')
  1218. {
  1219. load_config(data+strlen(sig_str),len-strlen(sig_str));
  1220. success=0;
  1221. }
  1222. }
  1223. GlobalFree((HGLOBAL)data);
  1224. }
  1225. LeaveCriticalSection(&g_render_cs);
  1226. return success;
  1227. }
  1228. /// smp fun
  1229. void C_RenderListClass::smp_Render(int minthreads, C_RBASE2 *render, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
  1230. {
  1231. int x;
  1232. smp_parms.nthreads=minthreads;
  1233. if (!smp_parms.hQuitHandle) smp_parms.hQuitHandle=CreateEvent(NULL,TRUE,FALSE,NULL);
  1234. smp_parms.vis_data_ptr=visdata;
  1235. smp_parms.isBeat=isBeat;
  1236. smp_parms.framebuffer=framebuffer;
  1237. smp_parms.fbout=fbout;
  1238. smp_parms.w=w;
  1239. smp_parms.h=h;
  1240. smp_parms.render=render;
  1241. for (x = 0; x < minthreads; x ++)
  1242. {
  1243. if (x >= smp_parms.threadTop)
  1244. {
  1245. DWORD id;
  1246. smp_parms.hThreadSignalsStart[x]=CreateEvent(NULL,FALSE,TRUE,NULL);
  1247. smp_parms.hThreadSignalsDone[x]=CreateEvent(NULL,FALSE,FALSE,NULL);
  1248. smp_parms.hThreads[x]=CreateThread(NULL,0,smp_threadProc,(LPVOID)(x),0,&id);
  1249. smp_parms.threadTop=x+1;
  1250. }
  1251. else
  1252. SetEvent(smp_parms.hThreadSignalsStart[x]);
  1253. }
  1254. WaitForMultipleObjects(smp_parms.nthreads,smp_parms.hThreadSignalsDone,TRUE,INFINITE);
  1255. }
  1256. DWORD WINAPI C_RenderListClass::smp_threadProc(LPVOID parm)
  1257. {
  1258. int which=(int)parm;
  1259. HANDLE hdls[2]={smp_parms.hThreadSignalsStart[which],smp_parms.hQuitHandle};
  1260. for (;;)
  1261. {
  1262. if (WaitForMultipleObjects(2,hdls,FALSE,INFINITE) == WAIT_OBJECT_0 + 1) return 0;
  1263. smp_parms.render->smp_render(which,smp_parms.nthreads,
  1264. *(char (*)[2][2][576])smp_parms.vis_data_ptr,
  1265. smp_parms.isBeat,smp_parms.framebuffer,smp_parms.fbout,smp_parms.w,smp_parms.h);
  1266. SetEvent(smp_parms.hThreadSignalsDone[which]);
  1267. }
  1268. }
  1269. C_RenderListClass::_s_smp_parms C_RenderListClass::smp_parms;