⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_ds3d.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 3 页
字号:
 *
 * Returns free (unused) source stack slot
 * If none available sound stack will be increased
 *
 ***************************************************************
 */
static int find_handle(int new_sfx_id, int new_is3d)
{
	int			    free_sfx;
	stack_t         *snd;
    
    
    // At first do look for sound with same sfx ID and reuse it
    for (free_sfx = 0, snd = _stack; free_sfx < allocated_sounds; snd++, free_sfx++)
    {
        
        if (snd->permanent)
            continue;
/*
        if (!is_playing(snd)) 
        {
            if (same_sfx == 0 && snd->sfx_id == new_sfx_id && snd->dsbuffer)
            {
                same_sfx = i;
                continue;
            }

            if (snd->sfx_id && ++snd->LRU >= MAX_LRU)
                kill_sound(snd);
        }
*/
        if (snd->dsbuffer == 0)
            break;
            //free_sfx = i;

    }

    // No suitable resource found so increase sound stack
    if (free_sfx == allocated_sounds)
    {
        DBG_Printf("No free or same sfx found so increase stack (currently %d srcs)\n", allocated_sounds);
        free_sfx = reallocate_stack() ? free_sfx : -1;
    };
   
    return free_sfx;
        
}


/***************************************************************
 *
 * Recalculates volume from Doom scale to DirectSound scale
 *
 ***************************************************************
 */
static int recalc_volume(int base_vol, int steps)
{
    return (base_vol * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / steps
           + (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4));
}


/***************************************************************
 *
 * Updates sound volume of the DirectSound buffer
 *
 ***************************************************************
 */
static void UpdateSoundVolume (LPDIRECTSOUNDBUFFER lpSnd, int volume)
{
    /*volume = (volume * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / 256 +
                        (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4));

    IDirectSoundBuffer_SetVolume (lpSnd, volume);*/
    IDirectSoundBuffer_SetVolume (lpSnd, recalc_volume(volume, 256));
}


// --------------------------------------------------------------------------
// Update the panning for a secondary buffer, make sure it was created with
// DSBCAPS_CTRLPAN
// --------------------------------------------------------------------------
#define DSBPAN_RANGE    (DSBPAN_RIGHT-(DSBPAN_LEFT))

//Doom sounds pan range 0-255 (128 is centre)
#define SEP_RANGE       256             
static void Update2DSoundPanning (LPDIRECTSOUNDBUFFER lpSnd, int sep)
{
    HRESULT hr;
    hr = IDirectSoundBuffer_SetPan (lpSnd, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT);
    //if (FAILED(hr))
    //    CONS_Printf ("SetPan FAILED for sep %d pan %d\n", sep, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT);
}



/******************************************************************************
 *
 * Initialise driver and listener
 *
 *****************************************************************************/
EXPORT BOOL HWRAPI( Startup ) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
    HRESULT         hr;
    DSBUFFERDESC    desc;
    WAVEFORMATEX    wfm;
    DSCAPS          dscaps;
    DWORD           speakers;
    DWORD           speaker_config;
    DWORD           speaker_geometry;
    
    I_ErrorDS3D = FatalErrorFunction;
    DBG_Printf ("S_DS3D Init(): DirectSound3D driver for Doom Legacy v%d.%d\n", VERSION / 100, VERSION % 100);

    DBG_Printf("Initialising DirectSound3D...\n");
    hr = DirectSoundCreate( NULL, &DSnd, NULL);
    if (FAILED(hr))
    {
        DBG_Printf("Failed to obtain DirectSound\n");
        return FALSE;
    }

    hr = IDirectSound_SetCooperativeLevel(DSnd, snd_dev->hWnd, snd_dev->cooplevel);
    if (FAILED (hr))
    {
        DBG_Printf("Couldn't set coopertive level\n");
        return FALSE;
    }

    dscaps.dwSize = sizeof(DSCAPS);

    IDirectSound_GetCaps(DSnd, &dscaps);
    IDirectSound_GetSpeakerConfig(DSnd, &speakers);

    DBG_Printf("Sound hardware capabilities:\n");
    DBG_Printf("   Driver is %scertified.\n", (dscaps.dwFlags & DSCAPS_CERTIFIED) == DSCAPS_CERTIFIED?"":"not ");
    DBG_Printf("   Maximum hardware mixing buffers %d\n", dscaps.dwMaxHwMixingAllBuffers);
    DBG_Printf("   Maximum hardware 3D buffers %d\n", dscaps.dwFreeHw3DAllBuffers);

    speaker_config = DSSPEAKER_CONFIG(speakers);
    speaker_geometry = DSSPEAKER_GEOMETRY(speakers);

    DBG_Printf("Current speaker configuration: ");

    switch (speaker_config)
    {
        case DSSPEAKER_5POINT1:
            DBG_Printf("5.1 (5 speakers with subwoofer).\n");
            break;

        case DSSPEAKER_HEADPHONE:
            DBG_Printf("headphone.\n");
            break;

        case DSSPEAKER_MONO:
            DBG_Printf("single speaker (mono).\n");
            break;

        case DSSPEAKER_QUAD:
            DBG_Printf("quadrophonic\n");
            break;

        case DSSPEAKER_SURROUND:
            DBG_Printf("surround.\n");
            break;

        case DSSPEAKER_STEREO:
            DBG_Printf("stereo with %s geometry ",
                speaker_geometry == DSSPEAKER_GEOMETRY_WIDE
                    ? "wide (arc of 20 deg.)"
                    : speaker_geometry == DSSPEAKER_GEOMETRY_NARROW
                        ? "narrow (arc of 10 deg.)"
                        : speaker_geometry == DSSPEAKER_GEOMETRY_MIN
                            ? "min (arc of 5 deg.)"
                            : speaker_geometry == DSSPEAKER_GEOMETRY_MAX
                                ? "max (arc of 180 deg.)"
                                : "unknown"); 
            break;
        default:
            DBG_Printf("undetectable.\n");

    }

    update_mode = DS3D_IMMEDIATE;

    // Create primary sound buffer
    ZeroMemory(&desc, sizeof(DSBUFFERDESC));
    desc.dwSize = sizeof(DSBUFFERDESC);
    desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
    desc.dwBufferBytes = 0;
    desc.lpwfxFormat = NULL;

    hr = IDirectSound_CreateSoundBuffer(DSnd, &desc, &PrimaryBuffer, NULL);
    if (FAILED(hr))
    {
        DBG_Printf("CreateSoundBuffer FAILED (ErrNo %d)\n", hr);
        return FALSE;
    }

    // Query for 3D Listener object
    hr = IDirectSoundBuffer_QueryInterface(PrimaryBuffer,
            &IID_IDirectSound3DListener, (void **)&Listener); 
            
    if (FAILED( hr ) )
    {
        DBG_Printf("Couldn't obtain 3D Listener interface (ErrNo %d)\n", hr);
        return FALSE;
    }

    // Set up initial listsner parameters
    IDirectSound3DListener_SetDistanceFactor(Listener, (float)1/(float)72.0, DS3D_IMMEDIATE);
    IDirectSound3DListener_SetRolloffFactor(Listener, DS3D_DEFAULTROLLOFFFACTOR, DS3D_IMMEDIATE);
    listener_parms.dwSize = sizeof(DS3DLISTENER);
    IDirectSound3DListener_GetAllParameters(Listener, &listener_parms);
    
    ZeroMemory (&wfm, sizeof(WAVEFORMATEX));
    wfm.wFormatTag = WAVE_FORMAT_PCM;
    wfm.nChannels = 2;
    wfm.nSamplesPerSec = srate = snd_dev->sample_rate;
    wfm.wBitsPerSample = snd_dev->bps;
    wfm.nBlockAlign = wfm.wBitsPerSample / 8 * wfm.nChannels;
    wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign;

    if (snd_dev->cooplevel >= DSSCL_PRIORITY)
    {
        hr = IDirectSoundBuffer_SetFormat (PrimaryBuffer, &wfm);
        if (FAILED(hr))
            DBG_Printf ("Couldn't set primary buffer format.\n");
        
        DBG_Printf (" Compacting onboard sound-memory...");
        hr = IDirectSound_Compact (DSnd);
        DBG_Printf (" %s\n", SUCCEEDED(hr) ? "done" : "FAILED");
    }

    // Initially enables HRTF virtualization (may be changed later)
    virtualization = FALSE;

	_stack = NULL;
	allocated_sounds = 0;
    IDirectSoundBuffer_Play(PrimaryBuffer, 0, 0, DSBPLAY_LOOPING);
    return reallocate_stack();
}



/***************************************************************
 *
 * Shutdown driver
 *
 ***************************************************************
 */
EXPORT void HWRAPI( Shutdown ) (void)
{
    int     i;

    DBG_Printf ("S_DS3D Shutdown()\n");

    for (i = 0; i < allocated_sounds; i++)
    {
        StopSource(i);
        kill_sound(_stack + i);
    }

    if (_stack)
        free(_stack);

    if (Listener)
    {
        IDirectSound3DListener_Release(Listener);
        Listener = NULL;
    }

    if (PrimaryBuffer)
        RELEASE_BUFFER(PrimaryBuffer);

    if (DSnd)
    {
        IDirectSound_Release(DSnd);
        DSnd = NULL;
    }
    
}



EXPORT int HWRAPI (IsPlaying) (int handle)
{
    if (handle < 0 || handle >= allocated_sounds)
        return FALSE;

    return is_playing(_stack + handle);
}



static stack_t *setup_source(int handle, sfx_data_t *sfx, BOOL is_3dsource)
{
    stack_t                 *snd;
    //int                     handle;
    int                     data_length;
    LPDIRECTSOUNDBUFFER     dsbuffer = NULL;
    LPDIRECTSOUND3DBUFFER   ds3dbuffer = NULL;

    if (handle == NEW_HANDLE)
        handle = find_handle(sfx?sfx->id:0, is_3dsource);

    snd = _stack + handle;

    // Check for reused source
    if (snd->dsbuffer)
        return snd;

    data_length = sfx?sfx->length - 8:DSBSIZE_MIN;

    dsbuffer = create_buffer(sfx ? sfx->data : NULL, data_length, is_3dsource);
    if (dsbuffer)
    {
        if (is_3dsource)
        {
            ds3dbuffer = create_3dbuffer(dsbuffer, ds3dbuffer);
            if (!ds3dbuffer)
            {
                RELEASE_BUFFER(dsbuffer);
                return NULL;
            }
            snd->parameters.dwSize = sizeof(DS3DBUFFER);
            IDirectSound3DBuffer_GetAllParameters(ds3dbuffer, &snd->parameters);

        }
        snd->dsbuffer = dsbuffer;
        snd->dsbuffer3D = ds3dbuffer;
        snd->LRU = 0;
        snd->sfx_id = sfx ? sfx->id : 0;
        if (!is_3dsource)
            snd->permanent = 0;
        return snd;
    }
    return NULL;

}

/******************************************************************************
 *
 * Creates 2D (stereo) source
 *
 ******************************************************************************/
EXPORT int HWRAPI ( Add2DSource ) (source2D_data_t *src, sfx_data_t *sfx)
{
    stack_t *snd;

    snd = setup_source(NEW_HANDLE, sfx, IS_2DSOURCE);
    if (snd)
    {
        UpdateSoundVolume(snd->dsbuffer, src->volume);
        Update2DSoundPanning(snd->dsbuffer, src->sep);
    }
    return snd - _stack;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -