about.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #include "main.h"
  2. #include "api__in_vorbis.h"
  3. #include "resource.h"
  4. #include <strsafe.h>
  5. /*static UINT xiphframes_ids[12]={IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4,IDB_BITMAP5,IDB_BITMAP6,IDB_BITMAP7,IDB_BITMAP8,IDB_BITMAP9,IDB_BITMAP10,IDB_BITMAP11,IDB_BITMAP12};
  6. static HBITMAP xiphframes[12];*/
  7. static UINT xiphframes_ids[12]={IDB_PNG1,IDB_PNG2,IDB_PNG3,IDB_PNG4,IDB_PNG5,IDB_PNG6,IDB_PNG7,IDB_PNG8,IDB_PNG9,IDB_PNG10,IDB_PNG11,IDB_PNG12};
  8. static ARGB32 *xiphframes[12] = {0};
  9. static HBITMAP xiphframesBmp[12] = {0};
  10. static void slap(HWND wnd,int v)
  11. {
  12. long hi=GetWindowLong(wnd,4);
  13. if (v) hi+=v*1000;
  14. else hi=0;
  15. SetWindowLong(wnd,4,hi);
  16. }
  17. static CfgInt cfg_rpm("rpm",0);
  18. static int visible_rpm,visible_max_rpm;
  19. static char show_rpm=0;
  20. static DWORD last_visible_rpm;
  21. ARGB32 * loadImg(const void * data, int len, int *w, int *h, bool ldata=false)
  22. {
  23. FOURCC imgload = svc_imageLoader::getServiceType();
  24. int n = (int)mod.service->service_getNumServices(imgload);
  25. for(int i=0; i<n; i++)
  26. {
  27. waServiceFactory *sf = mod.service->service_enumService(imgload,i);
  28. if(sf)
  29. {
  30. svc_imageLoader * l = (svc_imageLoader*)sf->getInterface();
  31. if(l)
  32. {
  33. if(l->testData(data,len))
  34. {
  35. ARGB32* ret;
  36. if(ldata) ret = l->loadImageData(data,len,w,h);
  37. else ret = l->loadImage(data,len,w,h);
  38. sf->releaseInterface(l);
  39. return ret;
  40. }
  41. sf->releaseInterface(l);
  42. }
  43. }
  44. }
  45. return NULL;
  46. }
  47. ARGB32 * loadRrc(int id, wchar_t * sec, int *w, int *h, bool data=false)
  48. {
  49. DWORD size=0;
  50. HGLOBAL resourceHandle = WASABI_API_LOADRESFROMFILEW(sec, MAKEINTRESOURCEW(id), &size);
  51. if(resourceHandle)
  52. {
  53. ARGB32* ret = loadImg(resourceHandle,size,w,h,data);
  54. UnlockResource(resourceHandle);
  55. return ret;
  56. }
  57. return NULL;
  58. }
  59. static LRESULT WINAPI XiphProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
  60. {
  61. switch(msg)
  62. {
  63. case WM_CREATE:
  64. SetWindowLong(wnd,8,last_visible_rpm=GetTickCount());
  65. SetTimer(wnd,666,10,0);
  66. visible_rpm=-1;
  67. visible_max_rpm=-1;
  68. show_rpm=0;
  69. break;
  70. case WM_TIMER:
  71. if (wp==666)
  72. {
  73. long low=GetWindowLong(wnd,0);
  74. long hi=GetWindowLong(wnd,4);
  75. long org=low&~0xFFFF;
  76. int rpm=MulDiv(abs(hi),1000*60,12*0x10000);
  77. DWORD t=GetTickCount();
  78. DWORD ot=(DWORD)SetWindowLong(wnd,8,t);
  79. bool redraw=0;
  80. if (rpm>25) show_rpm=1;
  81. if (cfg_rpm<rpm) cfg_rpm=rpm;
  82. if (show_rpm && (t&~0x3F)!=(ot&~0x3F))
  83. {
  84. wchar_t foo[128] = {0};
  85. if (visible_rpm<rpm || (visible_rpm>rpm && (t-last_visible_rpm)>333))
  86. {
  87. last_visible_rpm=t;
  88. visible_rpm=rpm;
  89. StringCchPrintfW(foo,128,WASABI_API_LNGSTRINGW(IDS_GAME_SPEED),rpm);
  90. SetDlgItemTextW(GetParent(wnd),IDC_RPM,foo);
  91. }
  92. if (visible_max_rpm!=cfg_rpm)
  93. {
  94. visible_max_rpm=cfg_rpm;
  95. StringCchPrintfW(foo,128,WASABI_API_LNGSTRINGW(IDS_BEST_RPM),(int)cfg_rpm);
  96. SetDlgItemTextW(GetParent(wnd),IDC_RPM2,foo);
  97. }
  98. }
  99. low+=hi*(t-ot);
  100. while(low<0) low+=12*0x10000;
  101. while(low>=12*0x10000) low-=12*0x10000;
  102. {
  103. int z=hi>>6;
  104. if (z) hi-=z;
  105. else if (hi>0) hi--;
  106. else if (hi<0) hi++;
  107. }
  108. SetWindowLong(wnd,0,low);
  109. SetWindowLong(wnd,4,hi);
  110. if (redraw || (low&~0xFFFF)!=org)
  111. {
  112. RedrawWindow(wnd,0,0,RDW_INVALIDATE);
  113. }
  114. KillTimer(wnd,666);
  115. SetTimer(wnd,666,10,0);
  116. }
  117. break;
  118. case WM_LBUTTONDOWN:
  119. slap(wnd,-1);
  120. break;
  121. case WM_RBUTTONDOWN:
  122. slap(wnd,1);
  123. break;
  124. case WM_MBUTTONDOWN:
  125. slap(wnd,0);
  126. break;
  127. case WM_PAINT:
  128. {
  129. int i=(GetWindowLong(wnd,0))>>16;
  130. HDC dc = CreateCompatibleDC(0);
  131. if (!xiphframesBmp[i])
  132. {
  133. int cur_w = 0, cur_h = 0;
  134. xiphframes[i] = loadRrc(xiphframes_ids[i], L"PNG", &cur_w, &cur_h, true);
  135. BITMAPINFO bmi = {0};
  136. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  137. bmi.bmiHeader.biWidth = cur_w;
  138. bmi.bmiHeader.biHeight = -cur_h;
  139. bmi.bmiHeader.biPlanes = 1;
  140. bmi.bmiHeader.biBitCount = 32;
  141. bmi.bmiHeader.biCompression = BI_RGB;
  142. void *bits = 0;
  143. if(xiphframesBmp[i]) DeleteObject(xiphframesBmp[i]);
  144. xiphframesBmp[i] = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
  145. memcpy(bits, xiphframes[i], cur_w * cur_h * 4);
  146. }
  147. if (xiphframesBmp[i])
  148. {
  149. HGDIOBJ foo = SelectObject(dc, xiphframesBmp[i]);
  150. HDC wdc = GetDC(wnd);
  151. RECT r = {0};
  152. GetClientRect(wnd, &r);
  153. FillRect(wdc, &r, GetSysColorBrush(COLOR_3DFACE));
  154. BLENDFUNCTION blendFn = {0};
  155. blendFn.BlendOp = AC_SRC_OVER;
  156. blendFn.SourceConstantAlpha = 255;
  157. blendFn.AlphaFormat = AC_SRC_ALPHA;
  158. AlphaBlend(wdc, 2, 2, r.right - 2, r.bottom - 2, dc, 0, 0, 63, 63, blendFn);
  159. ReleaseDC(wnd, wdc);
  160. SelectObject(dc, foo);
  161. }
  162. DeleteDC(dc);
  163. }
  164. break;
  165. case WM_DESTROY:
  166. {
  167. for (int i = 0; i < ARRAYSIZE(xiphframes_ids); i++)
  168. {
  169. if(xiphframesBmp[i]) DeleteObject(xiphframesBmp[i]); xiphframesBmp[i] = 0;
  170. if(xiphframes[i] && WASABI_API_MEMMGR) WASABI_API_MEMMGR->sysFree((void *)xiphframes[i]); xiphframes[i] = 0;
  171. }
  172. KillTimer(wnd,666);
  173. break;
  174. }
  175. };
  176. return DefWindowProc(wnd,msg,wp,lp);
  177. }
  178. static BOOL CALLBACK AboutProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
  179. {
  180. switch(msg)
  181. {
  182. case WM_INITDIALOG:
  183. {
  184. wchar_t tmp[1024] = {0}, tmp2[1024] = {0}, *t1 = tmp, *t2 = tmp2, text[1024] = {0};
  185. SetWindowTextW(wnd,WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_VORBIS_DECODER_OLD,text,1024));
  186. StringCchPrintfW(tmp,1024,WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),mod.description,__DATE__);
  187. // due to quirks with the more common resource editors, is easier to just store the string
  188. // internally only with \n and post-process to be \r\n (as here) so it will appear correctly
  189. // on new lines as is wanted (silly multiline edit controls)
  190. while(t1 && *t1 && (t2 - tmp2 < 1024))
  191. {
  192. if(*t1 == L'\n')
  193. {
  194. *t2 = L'\r';
  195. t2 = CharNextW(t2);
  196. }
  197. *t2 = *t1;
  198. t1 = CharNextW(t1);
  199. t2 = CharNextW(t2);
  200. }
  201. SetDlgItemTextW(wnd,IDC_ABOUT_TEXT,tmp2);
  202. // fixes the incorrect selection of the text on dialog opening
  203. PostMessage(GetDlgItem(wnd,IDC_ABOUT_TEXT),EM_SETSEL,-1,0);
  204. return 1;
  205. }
  206. case WM_COMMAND:
  207. if (wp==IDOK || wp==IDCANCEL)
  208. {
  209. do_cfg(1);
  210. EndDialog(wnd,0);
  211. }
  212. break;
  213. }
  214. return 0;
  215. }
  216. void About(HWND hwndParent)
  217. {
  218. static char got_xiph;
  219. if (!got_xiph)
  220. {
  221. WNDCLASS wc=
  222. {
  223. 0,
  224. XiphProc,
  225. 0,
  226. 12,
  227. WASABI_API_LNG_HINST,
  228. 0,
  229. LoadCursor(0,IDC_ARROW),
  230. 0,
  231. 0,
  232. L"XIPH_CLASS",
  233. };
  234. RegisterClassW(&wc);
  235. got_xiph=1;
  236. }
  237. WASABI_API_DIALOGBOXW(IDD_ABOUT,hwndParent,AboutProc);
  238. }