avstut00.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /**
  2. Example Winamp AVS plug-in
  3. Copyright (c) 2000, Nullsoft Inc.
  4. Hello, welcome to the first Advanced Visualization
  5. Studio tutorial!
  6. The hope is that together, we can learn to utilize
  7. AVS's powerful features: Namely direct access to the
  8. frame buffer, EZ beat detection, and the ability to
  9. stack plug-ins written by other developers for an
  10. infinite array of possible effects.
  11. I hereby present:
  12. Tutorial 0: BOX-
  13. Simplicity at its finest. Displays a rectangle on
  14. screen on every beat. Oh, and you can change its color
  15. too... Check avstut00.avs for a demonstration of a
  16. spinning rectangle's power!
  17. good luck and have fun!
  18. **/
  19. #include <windows.h>
  20. #include "resource.h"
  21. #include "avs_ape.h"
  22. #define MOD_NAME "Tutorials / BOX v1.0"
  23. #define UNIQUEIDSTRING "Nullsoft Tut0: BOX"
  24. // extended APE api support
  25. APEinfo *g_extinfo;
  26. extern "C"
  27. {
  28. void __declspec(dllexport) _AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
  29. {
  30. g_extinfo = ptr;
  31. }
  32. }
  33. class C_THISCLASS : public C_RBASE
  34. {
  35. protected:
  36. public:
  37. C_THISCLASS();
  38. virtual ~C_THISCLASS();
  39. virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
  40. virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
  41. virtual char *get_desc();
  42. virtual void load_config(unsigned char *data, int len);
  43. virtual int save_config(unsigned char *data);
  44. int enabled; // toggles plug-in on and off
  45. int color; // color of rectangle
  46. };
  47. // global configuration dialog pointer
  48. static C_THISCLASS *g_ConfigThis;
  49. // global DLL instance pointer (not needed in this example, but could be useful)
  50. static HINSTANCE g_hDllInstance;
  51. // this is where we deal with the configuration screen
  52. static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  53. {
  54. switch (uMsg)
  55. {
  56. case WM_INITDIALOG:
  57. if (g_ConfigThis->enabled)
  58. {
  59. CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
  60. }
  61. return 1;
  62. case WM_DRAWITEM:
  63. DRAWITEMSTRUCT *di;
  64. di=(DRAWITEMSTRUCT *)lParam;
  65. if (di->CtlID == IDC_DEFCOL)
  66. {
  67. int w;
  68. int color;
  69. w=di->rcItem.right-di->rcItem.left;
  70. color=g_ConfigThis->color;
  71. color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
  72. // paint nifty color button
  73. HBRUSH hBrush,hOldBrush;
  74. LOGBRUSH lb={BS_SOLID,color,0};
  75. hBrush = CreateBrushIndirect(&lb);
  76. hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
  77. Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
  78. SelectObject(di->hDC,hOldBrush);
  79. DeleteObject(hBrush);
  80. }
  81. return 0;
  82. case WM_COMMAND:
  83. // see if enable checkbox is checked
  84. if (LOWORD(wParam) == IDC_CHECK1)
  85. {
  86. g_ConfigThis->enabled= (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0);
  87. }
  88. // is colorbox is selected?
  89. if (LOWORD(wParam) == IDC_DEFCOL)
  90. {
  91. static COLORREF custcolors[16];
  92. int *a;
  93. CHOOSECOLOR cs;
  94. a=&g_ConfigThis->color;
  95. cs.lStructSize = sizeof(cs);
  96. cs.hwndOwner = hwndDlg;
  97. cs.hInstance = 0;
  98. cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
  99. cs.lpCustColors = custcolors;
  100. cs.Flags = CC_RGBINIT|CC_FULLOPEN;
  101. // go to windows color selection screen
  102. if (ChooseColor(&cs))
  103. {
  104. *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
  105. }
  106. InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
  107. }
  108. return 0;
  109. }
  110. return 0;
  111. }
  112. // set up default configuration
  113. C_THISCLASS::C_THISCLASS()
  114. {
  115. //set initial color
  116. color=RGB(255,0,0);
  117. enabled=1;
  118. }
  119. // virtual destructor
  120. C_THISCLASS::~C_THISCLASS()
  121. {
  122. }
  123. // RENDER FUNCTION:
  124. // render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
  125. // used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
  126. // w and h are the-*/ width and height of the screen, in pixels.
  127. // isBeat is 1 if a beat has been detected.
  128. // visdata is in the format of [spectrum:0,wave:1][channel][band].
  129. int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
  130. {
  131. int halfw;
  132. int halfh;
  133. // is this effect on?
  134. if (!enabled)
  135. {
  136. return 0;
  137. }
  138. // did we just hit a beat?
  139. if(isBeat)
  140. {
  141. // draw our magic box
  142. halfw=w/2;
  143. halfh=h/2;
  144. framebuffer+=(((halfh/2)*w)+ (halfw/2));
  145. for(int j=0;j<halfh;j++)
  146. {
  147. for(int i=0;i<halfw;i++)
  148. {
  149. framebuffer[i]=color;
  150. }
  151. framebuffer+=w;
  152. }
  153. }
  154. return 0;
  155. }
  156. HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
  157. {
  158. g_ConfigThis = this;
  159. return CreateDialog(hInstance,MAKEINTRESOURCE(IDD_CONFIG),hwndParent,g_DlgProc);
  160. }
  161. char *C_THISCLASS::get_desc(void)
  162. {
  163. return MOD_NAME;
  164. }
  165. // load_/save_config are called when saving and loading presets (.avs files)
  166. #define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
  167. void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
  168. {
  169. int pos=0;
  170. // always ensure there is data to be loaded
  171. if (len-pos >= 4)
  172. {
  173. // load activation toggle
  174. enabled=GET_INT();
  175. pos+=4;
  176. }
  177. if (len-pos >= 4)
  178. {
  179. // load the box color
  180. color=GET_INT();
  181. pos+=4;
  182. }
  183. }
  184. // write configuration to data, return length. config data should not exceed 64k.
  185. #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
  186. int C_THISCLASS::save_config(unsigned char *data)
  187. {
  188. int pos=0;
  189. PUT_INT(enabled);
  190. pos+=4;
  191. PUT_INT(color);
  192. pos+=4;
  193. return pos;
  194. }
  195. // export stuff
  196. C_RBASE *R_RetrFunc(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
  197. {
  198. if (desc)
  199. {
  200. strcpy(desc,MOD_NAME);
  201. return NULL;
  202. }
  203. return (C_RBASE *) new C_THISCLASS();
  204. }
  205. extern "C"
  206. {
  207. __declspec (dllexport) int _AVS_APE_RetrFunc(HINSTANCE hDllInstance, char **info, int *create) // return 0 on failure
  208. {
  209. g_hDllInstance=hDllInstance;
  210. *info=UNIQUEIDSTRING;
  211. *create=(int)(void*)R_RetrFunc;
  212. return 1;
  213. }
  214. };
  215. /**
  216. Final Thoughts:
  217. Alright! Hopefully you guys can take the next step
  218. and display more than just a colored rectangle ;) The
  219. exciting thing is, each time you write an AVS plug-in,
  220. you exponentially increase AVS's potential, unlocking
  221. the possibility of an effect you never expected. Good
  222. luck, I hope this has helped!
  223. See you next time!
  224. **/