Box source code here

From Winamp Developer Wiki
Revision as of 14:09, 25 September 2008 by Tarik (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Breadcrumb -- Wiki Main : Skin Developer : Visual Developer : Plug-in Developer : Articles Page : FAQ : Glossary

 #include <windows.h>
 #include "resource.h"
 #include "avs_ape.h"
 
// this will be the directory and APE name displayed in
// the AVS Editor
 #define MOD_NAME "Tutorials / BOX v1.0"
 
// this is how WVS will recognize this APE internally
  #define UNIQUEIDSTRING "Nullsoft Tut0: BOX"
  class C_THISCLASS : public C_RBASE
  {protected:
  public:
  C_THISCLASS();
  virtual ~C_THISCLASS();
  virtual int render(char visdata[2][2][576], int isBeat,
   int *framebuffer, int *fbout, int w, int h);
  virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
  virtual char *get_desc();
  virtual void load_config(unsigned char *data, int len);
  virtual int  save_config(unsigned char *data);
  int enabled;  // toggles plug-in on and off
                // (a good idea for any APE)
  int color;		// color of rectangle};
 
// global configuration dialog pointer
static C_THISCLASS *g_ConfigThis;
// global DLL instance pointer (not needed in this
// example, but is useful)static HINSTANCE g_hDllInstance;
// this is where we deal with the configuration screen
static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg,
WPARAM wParam,LPARAM lParam)
{
 switch (uMsg)
 {
  case WM_INITDIALOG:
  if (g_ConfigThis->enabled)
  {
   CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
  }
  return 1;
  case WM_DRAWITEM:
  DRAWITEMSTRUCT *di;
  di=(DRAWITEMSTRUCT *)lParam;
  if (di->CtlID == IDC_DEFCOL)
  {
   int w;
   int color;
   w=di->rcItem.right-di->rcItem.left;
   color=g_ConfigThis->color;
   color = ( (color>>16)&0xff) |
   (color&0xff00) |
   ((color<<16)&0xff0000);
 
   // paint nifty color button
   HBRUSH hBrush,hOldBrush;
   LOGBRUSH lb={BS_SOLID,color,0};
   hBrush = CreateBrushIndirect(&lb);
   hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
   Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,
   di->rcItem.right,di->rcItem.bottom);
   SelectObject(di->hDC,hOldBrush);
   DeleteObject(hBrush);
   }
  return 0;
  case WM_COMMAND:
 
  // see if enable checkbox is checked
  if (LOWORD(wParam) == IDC_CHECK1)
   {
    g_ConfigThis->enabled=
    (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0);
   }
 
   // is colorbox is selected?
  if (LOWORD(wParam) == IDC_DEFCOL)
   {
    static COLORREF custcolors[16];
    int *a;
    CHOOSECOLOR cs;
    a=&g_ConfigThis->color;
    cs.lStructSize = sizeof(cs);
    cs.hwndOwner = hwndDlg;
    cs.hInstance = 0;
    cs.rgbResult = ((*a>>16)&0xff)|
     (*a&0xff00)|
     ((*a<<16)&0xff0000);
    cs.lpCustColors = custcolors;
    cs.Flags = CC_RGBINIT|CC_FULLOPEN;
 
   // go to windows color selection screen
   if (ChooseColor(&cs))
   {
    *a = ((cs.rgbResult>>16)&0xff)|
    (cs.rgbResult&0xff00)|
    ((cs.rgbResult<<16)&0xff0000);
   }
   InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),
    NULL,TRUE);
   }
   return 0;
   }
   return 0;
   }
 
// set up default configuration
C_THISCLASS::C_THISCLASS()
{
 //set initial color
 color=RGB(255,0,0);
 enabled=1;}
 
// virtual destructor
C_THISCLASS::~C_THISCLASS()
{
}
 
/* RENDER FUNCTION:
render should return 0 if it only used framebuffer,
or 1 if the new output data  is in fbout.
this is used when you want to do something that you'd otherwise
need to make a copy of the framebuffer.
w and h are the width and height of the screen, in pixels.
isBeat is 1 if a beat has been detected.
visdata is in the format of [spectrum:0,wave:1][channel][band].
*/
 
int C_THISCLASS::render(char visdata[2][2][576], int isBeat,
		int *framebuffer, int *fbout, int w, int h)
{
 int halfw;
 int halfh;
 
 // is this effect on?
 if (!enabled)
 {
  return 0;
 }
 
 // did we just hit a beat?
 if(isBeat)
 {
  // draw our magic box
  halfw=w/2;
  halfh=h/2;
  framebuffer+=(((halfh/2)*w)+ (halfw/2));
  for(int j=0;j<halfh;j++)
   {
    for(int i=0;i<halfw;i++)
    {
     framebuffer[i]=color;
    }
    framebuffer+=w;
    }
  }
  return 0;
  }
 
HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
// return NULL if no config dialog possible
{
 g_ConfigThis = this;
 return CreateDialog(hInstance,MAKEINTRESOURCE(IDD_CONFIG),
  hwndParent,g_DlgProc);
}
char *C_THISCLASS::get_desc(void)
{
 return MOD_NAME;
}
 
// load_/save_config are called when saving and loading
// presets (.avs files)
 
#define GET_INT() (data[pos]|(data[pos+1]<<8)|\
  (data[pos+2]<<16)|(data[pos+3]<<24))
// read configuration of max length "len" from data.
 
void C_THISCLASS::load_config(unsigned char *data, int len)
{
 int pos=0;
 // always ensure there is data to be loaded
 if (len-pos >= 4)
  {
   // load activation toggle
   enabled=GET_INT();
   pos+=4;
  }
 
 if (len-pos >= 4)
  {
   // load the box color
   color=GET_INT();
   pos+=4;
  }
}
 
 
// write configuration to data, return length.
// config data should not exceed 64k.
#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
 
int  C_THISCLASS::save_config(unsigned char *data)
{
 int pos=0;
 
 PUT_INT(enabled);
 pos+=4;
 
 PUT_INT(color);
 pos+=4;
 
 return pos;
}
 
/*
export stuff
creates a new effect object if desc is NULL, otherwise
fills in desc with description
*/
C_RBASE *R_RetrFunc(char *desc)
{
 if (desc)
 {
  strcpy(desc,MOD_NAME);
  return NULL;
 }
 return (C_RBASE *) new C_THISCLASS();
}
 // allows AVS to retrieve this APE module
extern "C"
{
 __declspec (dllexport) int _AVS_APE_RetrFunc(HINSTANCE\
  hDllInstance, char **info, int *create)
  // return 0 on failure
 {
  g_hDllInstance=hDllInstance;
  *info=UNIQUEIDSTRING;
  *create=(int)(void*)R_RetrFunc;
  return 1;
 }
};