ObjReader Community

Programming Art => Eye Candies => Topic started by: Patrice Terrier on September 19, 2024, 06:23:34 pm

Title: BassBox Plugin 64-bit
Post by: Patrice Terrier on September 19, 2024, 06:23:34 pm
The purpose of this VS2022 application is to switch easily from one plugin to another to check the OpenGL FPO effects transposed to 64-bit.
Most of them inherit from the original 32-bit version written long ago in PowerBASIC.

(http://www.objreader.com/download/images/plugin64.jpg)

To navigate from one plugin to another move the cursor to the left or right edge of the window, and click on the auto/hide arrow.

Use drag & drop to play a specific audio file, and see how the effects interact with it.

Here is the BBP API to use to communicate with the plugin DLL.
See in the WM_TIMER message the gl_DrawScene() code using BBP_RenderOpenGL to pass the wimdata pointer to the DLL.

Code: [Select]
#pragma once
typedef ULONGLONG QWORD;

const int BBP_RENDER       = 1;       // Render the scene.
const int BBP_CREATE       = 2;       // Retrieve Title, Name, Version, Render mode.
const int BBP_INIT         = 3;       // Init the OpenGL.
const int BBP_SIZE         = 4;       // The size of the control has changed.
const int BBP_KEYBOARD     = 5;       // All keyborad message.
const int BBP_MOUSE        = 6;       // All mouse messages.
const int BBP_DESTROY      = 7;       // Free Up resources.
const int BBP_NEWSOUND     = 8;       // We are playing a new sound file.

const int BBP_GDIPLUS      = 0;       // GDImage GDIPLUS compatible mode.
const int BBP_OPENGL       = 1;       // OpenGL mode.
const int BBP_DIRECTX      = 2;       // DirectX mode (for future extension).

const int BBP_SUCCESS      = 0;
const int BBP_ERROR        = -1;

typedef struct {
    UINT msg;                   // The plugin's message (see above constant list).
    HWND parent;                // The parent window handle.
    HDC dc;                     // The parent window DC (while in play mode).
    HGLRC rc;                   // The parent OpenGL RC (while in play mode).
    WORD lpeak;                 // The left audio channel peak value (while in play mode).
    WORD rpeak;                 // The right audio channel peak value (while in play mode).
    char title[32];             // Plugin's name or title.
    char author[64];            // Plugin's author name.
    DWORD version;              // LOWRD major, HIWRD minor.
    long renderto;              // BBP_GDIPLUS, BBP_OPENGL, BBP_DIRECTX.
    long backargb;              // Default ARGB color background.
    float* fftdata;             // dword pointer to the FFT() as single array.
    WORD fftsize;               // Size of the FFT array.

    UINT winmsg;                // True Windows message.
    WPARAM wparam;              // wParam
    LPARAM lparam;              // lParam

    short* wimdata;             // dword pointer to the wave MM_WIM_DATA.
    QWORD medialength;          // Media length.
    QWORD mediapos;             // Media pos.

    char reserved[50];          // Reserved for future extension.
} BBPLUGIN;

static FARPROC BBP_ProcHandle(IN FARPROC hProc, IN long RW) {
    static FARPROC WasHproc;
    if (RW) WasHproc = hProc;
    return WasHproc;
}

static long BBP_Plugin(OUT BBPLUGIN &BBP) {
    long nRet = BBP_ERROR;
    if (IsWindow(gP.hGL)) {
        HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
        if (glRC) {
            long_proc (BBPLUGIN*);
            zProc hProc = (zProc) BBP_ProcHandle(0, 0);
            if (hProc) { nRet = hProc(&BBP); }
        }
    }
    return nRet;
}

static WCHAR* BBP_ActivePlugin(IN WCHAR* sPluginName, IN long RW) {
    static WCHAR sWasPluginName[MAX_PATH];
    if (RW) { wcscopy(sWasPluginName, sPluginName); }
    return sWasPluginName;
}

static void MarqueeUpdate() {
    WCHAR drive[_MAX_DRIVE]; ClearMemory(drive, sizeof(drive));
    WCHAR dir[_MAX_DIR]; ClearMemory(dir, sizeof(dir));
    WCHAR fname[_MAX_FNAME]; ClearMemory(fname, sizeof(fname));
    WCHAR ext[_MAX_EXT]; ClearMemory(ext, sizeof(ext));
    wsplitpath(gB.audiofile, drive, dir, fname, ext);
    ClearMemory(gP.plugintitle, sizeof(gP.plugintitle));
    wcscopy(gP.plugintitle, gP.title, MAX_PATH * 2);
    Add_Str(gP.plugintitle, gP.version);
    Add_Str(gP.plugintitle, L" by "); Add_Str(gP.plugintitle, gP.author);
    Add_Str(gP.plugintitle, L", playing \""); Add_Str(gP.plugintitle, fname); Add_Str(gP.plugintitle, ext); Add_Str(gP.plugintitle, L"\"");
    ZD_SetObjectText(ID_COPYRIGHT, gP.plugintitle);
}

static void BBP_Reset() {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    BBP.msg = BBP_CREATE;
    BBP_Plugin(BBP);

    ClearMemory(gP.title, sizeof(gP.title));
    wcscopy(gP.title, cswconv(BBP.title), strSize(gP.title));// C string to WCHAR
    ClearMemory(gP.author, sizeof(gP.author));
    wcscopy(gP.author, cswconv(BBP.author), strSize(gP.author));// C string to WCHAR

    BYTE majorVersion = (BYTE)(BBP.version & 0xFF);
    BYTE minorVersion = (BYTE)((BBP.version >> 8) & 0xFF);
    ClearMemory(gP.version, sizeof(gP.version));
    swprintf(gP.version, strSize(gP.version), L" (%d.%d)", majorVersion, minorVersion);

    MarqueeUpdate();

    //BBProc(BBP);
    if (BBP.renderto == BBP_OPENGL) {

        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHT0);
        glDisable(GL_LIGHT1);
        glDisable(GL_LIGHT2);
        glDisable(GL_LIGHT3);
        glDisable(GL_LIGHT4);
        glDisable(GL_LIGHT5);
        glDisable(GL_LIGHT6);
        glDisable(GL_LIGHT7);
        glDisable(GL_LIGHTING);
        glDisable(GL_COLOR_MATERIAL);
        glDisable(GL_ALPHA_TEST);
        glDisable(GL_NORMALIZE);

        glDisable(GL_LINE_SMOOTH);

        glGetError();

    }
}

//long BBProc (OUT BBPLUGIN &BBP);
static void BBP_Detached(IN HWND hWnd, OUT HMODULE &hLib) {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    if (hLib) {
        BBP.msg = BBP_DESTROY;
        BBP.parent = hWnd;
        BBP_Plugin(BBP);
        //BBProc(BBP);

        // use brute force to delete any existing texture
        long Tmax = 64;
        long* DT = new long[Tmax]; memset(DT, 0, Tmax);
        for (long K = 0; K < Tmax; K++) { DT[K] = K; }
        glDeleteTextures(Tmax, (GLuint*)&DT[0]);
        delete[] DT;

        BBP_ProcHandle(0, 1); FreeLibrary(hLib); hLib = 0;
    }
}

static void BBP_ResizeOpenGL() {
    if (IsWindow(gP.hGL)) {
        BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
        BBP.msg          = BBP_SIZE;
        BBP.parent       = gP.hGL;
        BBP_Plugin(BBP);
        //BBProc(BBP);
    }
}

// Load/unload plugin DLL to/from memory
static long BBP_LoadPlugin(IN HWND hWnd, IN WCHAR* zPlugin) {
    long nDone = BBP_ERROR;
    long nLen = lstrlen(zPlugin);
    if ((nLen) && (_wcsicmp(zPlugin, BBP_ActivePlugin(0,0)) != 0)) {
        if (FileExist(zPlugin)) {
            if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
            gP.hLib = LoadLibrary(zPlugin);
            if (gP.hLib) {
                FARPROC hProc = GetProcAddress(gP.hLib, "BBProc");
                if (hProc) {
                    BBP_ProcHandle(hProc, 1);
                    BBP_ActivePlugin(zPlugin, 1);
                    // Reset plugin to default
                    BBP_Reset();
                    nDone = BBP_SUCCESS;
                }
            }
        }
    } else if (nLen == 0) {
        if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
    }
    return nDone;
}

static long BBP_AttachPlugin(WCHAR* zPlugin) {
    gP.pluginloaded = 0;
    if (IsWindow(gP.hGL)) {
        if (BBP_LoadPlugin(gP.hGL, zPlugin) == BBP_SUCCESS) {
            gP.pluginloaded = -1;
            BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
            BBP.msg          = BBP_INIT;
            BBP.parent       = gP.hGL;
            BBP.dc           = (HDC) ZI_GetProperty(gP.hGL, ZI_GLDC);
            BBP.rc           = (HGLRC) ZI_GetProperty(gP.hGL, ZI_GLRC);
            BBP.backargb     = 0;
            BBP_Plugin(BBP);

            //if (IsWindowVisible(gP.hGL)) { SetMetadataText(ID_VIDEO_SIZE, gB.plugintitle); }

            BBP.msg          = BBP_SIZE;
            BBP_Plugin(BBP);

            wcscopy(gP.bin.lastplugin, zPlugin);

            gP.pluginloaded = -1;
        }
    }
    return gP.pluginloaded;
}

static void BBP_RenderOpenGL(IN DWORD nLevel, IN short* pInt) {

    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));

    HDC glDC = (HDC) (ZI_GetProperty(gP.hGL, ZI_GLDC));
    HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
    if (glRC) {

        BBP.msg          = BBP_RENDER;
        BBP.parent       = gP.hGL;
        BBP.dc           = glDC;
        BBP.rc           = glRC;
        BBP.lpeak        = SolvePeak(LOWORD(nLevel), 128);
        BBP.rpeak        = SolvePeak(HIWORD(nLevel), 128);
        BBP.backargb     = 0;
        BBP.fftdata      = (float*) BassChannelGetData();
        BBP.fftsize      = 256;
        BBP.medialength  = gB.medialength;
        BBP.mediapos     = gB.mediapos;
        BBP.wimdata      = pInt;

        BBP_Plugin(BBP);
        //BBProc(BBP);

        // Refresh display
        SwapBuffers(glDC);

        InvalidateRect(gP.hGL, NULL, 0);
        UpdateWindow(gP.hGL);
    }
    ReleaseDC(gP.hGL, glDC);
}

static void BBP_NewSound() {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    BBP.msg = BBP_NEWSOUND;
    BBP_Plugin(BBP);
}

If you are familiar with OpenGL programming, the VS2022 source code of each plugin is also attached in the Plugins_dll.7z

Title: Re: BassBox Plugin 64-bit
Post by: Patrice Terrier on October 09, 2024, 05:52:33 pm
The whole project has been updated with new plugins.