PDA

View Full Version : Vis plugin closes/crashes winamp after restart


CGL_Guardian
21st June 2002, 11:25
I seem to be having a problem with the closing of my plugin.

Currently I'm developing an XMMS plugin that also works with Winamp. To achieve this, I am using SDL (www.libsdl.org) for all my graphics. However, the problem I have is that when I try to stop the plugin and the restart it, Winamp quits (with no crash dialog).

Since I am still fairly new to windows programming (mostly develop on linux), I wonder if I'm doing something wrong. Can anyone help? (even an explanation of how winamp loads and unloads plugins would help).

Below is the code.

Thanks, Lance


/*
* Winamp SDL Test Visualisation Plugin
*/

#include <windows.h>
#include "SDL.h"
#include "vis.h"

static SDL_Surface *screen = NULL;
static Uint32 red = 0, green = 0;

/* returns a winampVisModule when requested. Used in hdr, below */
winampVisModule *getModule(int which);

/* "member" functions */
void config(struct winampVisModule *this_mod); /* configuration dialog */
int init(struct winampVisModule *this_mod); /* initialization for module */
int render(struct winampVisModule *this_mod); /* rendering for module */
void quit(struct winampVisModule *this_mod); /* deinitialization for module */

/* Module header, includes version, description, and address of the module retriever function */
winampVisHeader hdr = { VIS_HDRVER, "SDL Test Visualisation", getModule };

/* first module (oscilliscope) */
winampVisModule mod =
{
"SDL Testvis",
NULL, // hwndParent
NULL, // hDllInstance
0, // sRate
0, // nCh
25, // latencyMS
25, // delayMS
0, // spectrumNch
2, // waveformNch
{ 0, }, // spectrumData
{ 0, }, // waveformData
NULL,
init,
render,
quit
};


/* this is the only exported symbol. returns our main header.
if you are compiling C++, the extern "C" { is necessary, so we just #ifdef it */
#ifdef __cplusplus
extern "C" {
#endif
__declspec( dllexport ) winampVisHeader *winampVisGetHeader()
{
return &hdr;
}
#ifdef __cplusplus
}
#endif

/* Returns a pointer to the appropriate module based upon which */
winampVisModule *getModule(int which)
{
switch (which)
{
case 0: return &mod;
default:return NULL;
}
}

/*
* Set the pixel at (x, y) to the given value
* NOTE: The surface must be locked before calling this!
*/
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
*p = pixel;
break;

case 2:
*(Uint16 *)p = pixel;
break;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;

case 4:
*(Uint32 *)p = pixel;
break;
}
}

/* Initialise the module */
int init(struct winampVisModule *this_mod)
{
/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
return 1;
}
atexit(SDL_Quit);

/*
* Initialize the display in a 640x480 16-bit mode,
* requesting a software surface
*/
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE);
if ( screen == NULL )
{
printf("Couldn't set 640x480x16 video mode: %s\n",
SDL_GetError());
return 1;
}

SDL_WM_SetCaption("SDL Test Vis", NULL);

/* Setup colours */
red = SDL_MapRGB(screen->format, 255, 0, 0);
green = SDL_MapRGB(screen->format, 0, 255, 0);
return 0;
}

/* render function for oscilliscope. Returns 0 if successful,
1 if visualization should end.*/
int render(struct winampVisModule *this_mod)
{
int x, y;
Uint32 colour;
SDL_Event event;

/* Clear the screen */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,0,0,0));

/* Poll for events */
while(SDL_PollEvent(&event))
{
switch(event.type)
{
/* Keyboard event */
case SDL_KEYDOWN:
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
return 1;
break;
}
break;
}

/* SDL_QUIT event (window close) */
case SDL_QUIT:
{
return 1;
break;
}

default:
{
break;
}
}
}

/* Use data */
for (y = 0; y < this_mod->nCh; y ++)
{
for (x = 0; x < 576; x ++)
{
if (y == 0)
{
colour = red;
}
else
{
colour = green;
}

if (SDL_MUSTLOCK(screen))
{
SDL_LockSurface(screen);
}

putpixel(screen,20+x,(y*200+(this_mod->waveformData[y][x]^128))>>(this_mod->nCh-1),colour);

if (SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}
}
}

/* Update the screen */
SDL_UpdateRect(screen, 0, 0, 0, 0);

return 0;
}

/* Quit! */
void quit(struct winampVisModule *this_mod)
{
SDL_Quit();
}

schweitn
21st June 2002, 12:38
Wrong forum... this is for Winamp3 Development... you are developing a Winamp2 Plugin... The architectures are COMPLETELY different.

Could a mod move this please?

CGL_Guardian
25th June 2002, 04:57
Sorry ppl, I must of clicked the wrong forum.

Lance

:(