青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

創(chuàng)建游戲內核(19)【OO改良版】

 

本篇是創(chuàng)建游戲內核(18)【OO改良版】的續(xù)篇,關于該內核的細節(jié)說明請參閱創(chuàng)建游戲內核(19)


接口:

//======================================================================================
// This class encapsulate sound buffer playing.
//======================================================================================
typedef class SOUND_CHANNEL
{
    friend 
class SOUND;

public:
    SOUND_CHANNEL();
    ~SOUND_CHANNEL();

    IDirectSoundBuffer8*    get_ds_buffer();
    IDirectSoundNotify8*    get_ds_notify();

    BOOL create(SOUND_PTR sound, 
long frequency, short channels, short bits_per_sample);
    
void free();

    BOOL play(
const SOUND_DATA_PTR sound_data, long volume_percent, long loop_times);
    
void stop();

    
long get_volume();
    BOOL set_volume(
long percent);

    signed 
long get_pan();
    BOOL set_pan(signed 
long level);

    
long get_frequency();
    BOOL set_frequency(
long frequency);

    BOOL is_playing();

protected:
    BOOL _buffer_data();
    
void _update();

protected:
    SOUND_PTR               m_sound;         
// pointer to parent sound object
    IDirectSoundBuffer8*    m_ds_buffer;     // pointer to DirectSound buffer object
    IDirectSoundNotify8*    m_ds_notify;     // pointer to DirectSound notify object

    
short                   m_event_index;   

    
long                    m_volume;        // sound buffer volume
    signed long             m_pan;           // sound buffer pan
    BOOL                    m_is_playing;    // sound buffer playing flag
    long                    m_loop_times;    // loop times

    
long                    m_frequency;
    
short                   m_bits_per_sample;
    
short                   m_channels;

    SOUND_DATA              m_sound_data;

    
short                   m_load_section;  // sound section will to be loaded
    short                   m_stop_section;  // sound section will to be stoped
    short                   m_next_notify;   // sound notification index will to be played
} *SOUND_CHANNEL_PTR;

實現:
//------------------------------------------------------------------------------
// Constructor, initialize member data.
//------------------------------------------------------------------------------
SOUND_CHANNEL::SOUND_CHANNEL()
{
    m_sound     = NULL;
    m_ds_buffer = NULL;
    m_ds_notify = NULL;

    m_event_index = -1;

    m_volume     = 0;
    m_pan        = 0;
    m_frequency  = 0;
    m_is_playing = FALSE;
}

//------------------------------------------------------------------------------
// Destructor, release sound buffer and sound notification, set the event state 
// to nonsignaled.
//------------------------------------------------------------------------------
SOUND_CHANNEL::~SOUND_CHANNEL()
{
    free();
}

//------------------------------------------------------------------------------
// Release sound buffer and sound notification, set the event state to nonsignaled.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::free()
{
    
// stop any playback
    stop();

    
// release the sound notification and sound buffer
    release_com(m_ds_notify);    
    release_com(m_ds_buffer);

    
// release event from parent SOUND class
    m_sound->release_event(this, &m_event_index);

    
// set to no parent sound
    m_sound = NULL;
}

//------------------------------------------------------------------------------
// Stop playing DirectSound buffer.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::stop()
{
    
if(m_ds_buffer)
        m_ds_buffer->Stop();

    m_is_playing = FALSE;
}

//------------------------------------------------------------------------------
// Return pointer to DirectSound buffer.
//------------------------------------------------------------------------------
IDirectSoundBuffer8* SOUND_CHANNEL::get_ds_buffer()
{
    
return m_ds_buffer;
}

//------------------------------------------------------------------------------
// Return pointer to DirectSound notify.
//------------------------------------------------------------------------------
IDirectSoundNotify8* SOUND_CHANNEL::get_ds_notify()
{
    
return m_ds_notify;
}

//------------------------------------------------------------------------------
// Create sound buffer, set sound notification and event.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::create(SOUND_PTR sound, long frequency, short channels, short bits_per_sample)
{
    
// free a prior channel
    free();

    m_sound = sound;

    
if(m_sound == NULL || m_sound->get_directsound() == NULL)
        
return FALSE;

    
// save playback format
    m_frequency       = frequency;
    m_bits_per_sample = bits_per_sample;
    m_channels        = channels;

    WAVEFORMATEX _wave_format;

    
// create a new sound buffer for this channel, using specified format.

    ZeroMemory(&_wave_format, 
sizeof(WAVEFORMATEX));

    _wave_format.wFormatTag      = WAVE_FORMAT_PCM;
    _wave_format.nChannels       = (WORD) m_channels;
    _wave_format.nSamplesPerSec  = m_frequency;
    _wave_format.wBitsPerSample  = (WORD) m_bits_per_sample;
    _wave_format.nBlockAlign     = _wave_format.wBitsPerSample / 8 * _wave_format.nChannels;
    _wave_format.nAvgBytesPerSec = _wave_format.nSamplesPerSec * _wave_format.nBlockAlign;

    DSBUFFERDESC _buffer_desc;

    ZeroMemory(&_buffer_desc, 
sizeof(DSBUFFERDESC));

    _buffer_desc.dwSize          = 
sizeof(DSBUFFERDESC);
    _buffer_desc.dwFlags         = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | 
                                   DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
    _buffer_desc.dwBufferBytes   = g_sound_buffer_size;
    _buffer_desc.lpwfxFormat     = &_wave_format;

    IDirectSoundBuffer* _ds_buffer;

    
if(FAILED(m_sound->get_directsound()->CreateSoundBuffer(&_buffer_desc, &_ds_buffer, NULL)))
        
return FALSE;

    
// query for newer interface
    if(FAILED(_ds_buffer->QueryInterface(IID_IDirectSoundBuffer8, (void**) &m_ds_buffer)))
    {
        _ds_buffer->Release();
        
return FALSE;
    }

    
// release old object - we have the newer one now
    _ds_buffer->Release();

    
// create the notification interface
    if(FAILED(m_ds_buffer->QueryInterface(IID_IDirectSoundNotify8, (void**) &m_ds_notify)))
        
return FALSE;

    HANDLE _event_handle;

    
// get an event for this sound channel
    if(! m_sound->assign_event_for_sound_channel(this, &m_event_index, &_event_handle))
        
return FALSE;

    DSBPOSITIONNOTIFY _pos_notify[4];

    
// setup the 4 notification positions
    _pos_notify[0].dwOffset     = g_sound_buffer_chunk - 1;
    _pos_notify[0].hEventNotify = _event_handle;
    _pos_notify[1].dwOffset     = g_sound_buffer_chunk * 2 - 1;
    _pos_notify[1].hEventNotify = _event_handle;
    _pos_notify[2].dwOffset     = g_sound_buffer_chunk * 3 - 1;
    _pos_notify[2].hEventNotify = _event_handle;
    _pos_notify[3].dwOffset     = g_sound_buffer_size - 1;
    _pos_notify[3].hEventNotify = _event_handle;

    
if(FAILED(m_ds_notify->SetNotificationPositions(4, _pos_notify)))
        
return FALSE;

    
// set pan and default volume
    set_volume(100);
    set_pan(0);

    
return TRUE;
}

//------------------------------------------------------------------------------
// Play sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::play(const SOUND_DATA_PTR sound_data, long volume_percent, long loop_times)
{
    
if(sound_data == NULL || m_ds_buffer == NULL || m_ds_notify == NULL)
        
return FALSE;

    
// stop any playback
    stop();

    
// restore a lost buffer just in case
    m_ds_buffer->Restore();

    
// setup playing information
    m_sound_data.copy_sound_data(sound_data);

    
// set looping times
    m_loop_times = loop_times;

    
// calculate stop section position
    if(m_loop_times == 0)
        m_stop_section = -1;
    
else
        m_stop_section = (
short
            (((m_sound_data.m_buffer_size * m_loop_times) % g_sound_buffer_size) / g_sound_buffer_chunk) ;

    m_load_section = 0;

    
// load sound data into sound buffer from sound file or sound data object
    _buffer_data();
    _buffer_data();
    _buffer_data();
    _buffer_data();

    
// set the volume
    set_volume(volume_percent);

    
// set position and begin play

    m_next_notify = 0;

    
if(FAILED(m_ds_buffer->SetCurrentPosition(0)))
        
return FALSE;

    
if(FAILED(m_ds_buffer->Play(0, 0, DSBPLAY_LOOPING)))
        
return FALSE;

    
// flag as playing
    m_is_playing = TRUE;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer volume.
//------------------------------------------------------------------------------
long SOUND_CHANNEL::get_volume()
{
    
return m_volume;
}

//------------------------------------------------------------------------------
// Set volume for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_volume(long percent)
{
    
if(! set_ds_buffer_volume(m_ds_buffer, percent))
        
return FALSE;

    m_volume = percent % 101;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer pan.
//------------------------------------------------------------------------------
signed long SOUND_CHANNEL::get_pan()
{
    
return m_pan;
}

//------------------------------------------------------------------------------
// Set pan for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_pan(long level)
{
    
if(! set_ds_buffer_pan(m_ds_buffer, level))
        
return FALSE;    

    m_pan = level % 101;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer frequency.
//------------------------------------------------------------------------------
long SOUND_CHANNEL::get_frequency()
{
    
return m_frequency;
}

//------------------------------------------------------------------------------
// Set frequency for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_frequency(long frequency)
{
    
if(m_ds_buffer == NULL)
        
return FALSE;

    
if(FAILED(m_ds_buffer->SetFrequency(frequency)))
        
return FALSE;

    m_frequency = frequency;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Checks whether sound buffer is playing.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::is_playing()
{
    
if(m_sound == NULL || m_ds_buffer == NULL || m_ds_notify == NULL)
        
return FALSE;

    
return m_is_playing;
}

//------------------------------------------------------------------------------
// Load sound data into sound buffer from sound file or sound data object.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::_buffer_data()
{
    
if(m_ds_buffer == NULL)
        
return FALSE;

    
// setup position to load in
    long _lock_pos = (m_load_section % 4) * g_sound_buffer_chunk;

    
long  _size;
    
char* _ptr;

    
// lock sound buffer to get pointer to sound data
    if(FAILED(m_ds_buffer->Lock(_lock_pos, g_sound_buffer_chunk, (void**) &_ptr, (DWORD*) &_size, NULL, NULL, 0)))
        
return FALSE;

    
// clear out buffer if nothing left to load
    if(m_sound_data.m_left_size == 0)
        ZeroMemory(_ptr, _size);
    
else
    {
        
// load in the data - take looping into account
        long _load_size = _size;
        
long _load_pos  = 0;

        
// load sound data until specfied load _size is satisfied
        for(;;)
        {
            
if(m_sound_data.m_left_size > _load_size)
            {
                
// load into sound data from buffer
                memcpy(&_ptr[_load_pos], &m_sound_data.m_ptr[m_sound_data.m_file_curr_pos], _load_size);

                
// decrease _size of sound data needed to load, advance current sound buffer position.
                m_sound_data.m_left_size     -= _load_size;
                m_sound_data.m_file_curr_pos += _load_size;

                
break;
            }
            
else        // m_sound_data._left_size <= _load_size
            {
                
// load in sound data from buffer
                memcpy(&_ptr[_load_pos], &m_sound_data.m_ptr[m_sound_data.m_file_curr_pos], m_sound_data.m_left_size);

                
// decrease _size of sound data needed to load, advance current sound buffer position.
                _load_size -= m_sound_data.m_left_size;
                _load_pos  += m_sound_data.m_left_size;

                
// check if we need to stop loop
                if(m_loop_times >= 1)
                {
                    m_loop_times--;

                    
if(m_loop_times == 0)
                    {
                        
// clear out remaining buffer space
                        if(_load_size)
                            ZeroMemory(&_ptr[_load_pos], _load_size);

                        m_sound_data.m_left_size = 0L;
                        
break;
                    }
                }

                
// reset sound data current position and left _size
                m_sound_data.m_file_curr_pos = m_sound_data.m_file_start_pos;
                m_sound_data.m_left_size     = m_sound_data.m_buffer_size;

                
// set if we need to stop loading data
                if(_load_size == 0)
                    
break;
            }
        }
    }

    
// unlock the buffer
    m_ds_buffer->Unlock(_ptr, _size, NULL, 0);

    
// mark next section to load
    if(++m_load_section > 3)
        m_load_section = 0;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Update for sound buffer playing.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::_update()
{
    
// check for end of sound
    if(m_next_notify == m_stop_section && m_sound_data.m_left_size == 0)
        stop();
    
else
    {
        
// buffer in more data
        _buffer_data();

        
if(++m_next_notify > 3)
            m_next_notify = 0;
    }
}

測試代碼:
/*****************************************************************************
PURPOSE:
    Test for class SOUND, SOUND_DATA, SOUND_CHANNEL.
*****************************************************************************/


#include "core_common.h"
#include "core_framework.h"
#include "core_sound.h"

class APP : public FRAMEWORK
{
public:
    BOOL init()
    {
        
// Initialize DierctSound and DirectMusic.
        m_sound.init(g_hwnd, 22050, 1, 16, DSSCL_NORMAL);

        
// load into sound data from wave file
        m_sound_data[0].load_wav("test1.wav");
        m_sound_data[1].load_wav("test2.wav");
        
        
// create sound channel

        m_sound_channel[0].create(&m_sound, 
            m_sound_data[0].get_frequency(), m_sound_data[0].get_channels(), m_sound_data[0].get_bits_per_sample());

        m_sound_channel[1].create(&m_sound, 
            m_sound_data[1].get_frequency(), m_sound_data[1].get_channels(), m_sound_data[1].get_bits_per_sample());

        
// play sound
        m_sound_channel[0].play(&m_sound_data[0], 100, 1);
        m_sound_channel[1].play(&m_sound_data[1], 50, 0); 
// lopping forever   
        
        
return TRUE;
    }

    BOOL frame()
    {
        
return TRUE;
    }

    BOOL shutdown()
    {
        
return TRUE;
    }

private:
    SOUND m_sound;
    SOUND_DATA m_sound_data[2];
    SOUND_CHANNEL m_sound_channel[2];

    FILE* _fp;
};

int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    APP app;

    
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
        
return -1;
    
    app.run();

    
return 0;
}

posted on 2007-10-10 20:28 lovedday 閱讀(238) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区不卡免费| 久久免费视频在线观看| 国产精品美女久久久免费| 欧美日韩国产123区| 欧美精品一区二区精品网 | 麻豆9191精品国产| 久久性天堂网| 亚洲福利视频免费观看| 免费永久网站黄欧美| 欧美成人资源网| 亚洲黄色免费电影| 夜夜精品视频| 亚洲永久免费| 久久久精品性| 欧美成人69av| 欧美视频免费在线观看| 国产手机视频精品| 亚洲国产成人久久| 国产精品99久久久久久人| 久久er精品视频| 欧美大片一区| 亚洲天堂成人在线观看| 久久久精品国产99久久精品芒果| 欧美国产三区| 国产一区二区三区黄视频| 亚洲免费观看在线观看| 久久精品国产亚洲高清剧情介绍| 玖玖视频精品| 99视频超级精品| 久久久精品性| 国产精品国产三级欧美二区| 狠狠色综合色区| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 欧美成人免费播放| 国产精品99久久久久久白浆小说| 久久国产乱子精品免费女| 美女黄网久久| 国产精品一级在线| 亚洲人体一区| 久久国内精品视频| 亚洲精品综合久久中文字幕| 欧美在现视频| 国产精品久久久久77777| 亚洲国产一二三| 久久伊伊香蕉| 亚洲欧美在线免费观看| 欧美日韩在线一区二区| 亚洲精品国产精品乱码不99| 久久精品国产第一区二区三区最新章节| 亚洲国产精品久久| 老司机免费视频一区二区| 午夜精品福利一区二区蜜股av| 欧美jizzhd精品欧美巨大免费| 亚洲愉拍自拍另类高清精品| 欧美乱妇高清无乱码| 亚洲日韩欧美视频一区| 美国成人直播| 欧美一区二区在线免费观看| 国产精品视频久久| 亚洲影院免费| 一区二区三区久久| 欧美日韩综合网| 在线中文字幕日韩| 亚洲精品日韩精品| 欧美精品激情在线观看| 亚洲日韩中文字幕在线播放| 欧美成人黑人xx视频免费观看| 久久精品国产免费观看| 韩国av一区二区三区在线观看| 久久免费精品日本久久中文字幕| 欧美一区二区三区在线视频 | 欧美一区二区精品| 亚洲综合首页| 国产午夜亚洲精品不卡| 久久久久88色偷偷免费| 亚欧美中日韩视频| 一区二区三区在线高清| 麻豆久久久9性大片| 欧美.日韩.国产.一区.二区| 亚洲伦理一区| 亚洲视频在线观看视频| 国产伦精品一区二区三区高清版| 久久不射2019中文字幕| 久久国产精品久久久久久| 亚洲福利在线视频| 亚洲乱码视频| 国产一区二区成人| 亚洲成人资源| 国产精品成人一区二区三区夜夜夜| 欧美一区二区三区免费观看视频| 欧美一区午夜精品| 亚洲精品在线二区| 亚洲欧美激情一区二区| 亚洲电影免费观看高清| 99在线精品免费视频九九视| 国产一区二区三区网站| 亚洲黄色影片| 国内一区二区三区| 亚洲精品一区中文| 激情综合在线| 亚洲一区二区三区涩| 亚洲国产精品久久久久秋霞蜜臀| 夜夜嗨av一区二区三区网页| 怡红院精品视频| 亚洲天堂偷拍| 亚洲精品一二区| 久久精品国产一区二区三区免费看| 日韩视频中文| 久久综合图片| 久久久精品动漫| 国产精品福利片| 久久蜜桃香蕉精品一区二区三区| 美女国产一区| 亚洲一卡二卡三卡四卡五卡| 国产女人18毛片水18精品| 蜜臀av一级做a爰片久久| 一区二区三区四区蜜桃| 欧美一区综合| 亚洲视频在线视频| 你懂的国产精品永久在线| 亚洲欧美韩国| 欧美精选一区| 亚洲观看高清完整版在线观看| 国产尤物精品| 午夜精品久久久久久99热| 亚洲午夜女主播在线直播| 欧美a级片网站| 嫩草国产精品入口| 一区二区三区在线免费视频| 欧美夜福利tv在线| 欧美一区二区黄| 国产精品欧美风情| 亚洲无线观看| 午夜亚洲一区| 国产精品露脸自拍| 亚洲天堂av高清| 欧美亚洲日本国产| 国产精品一级在线| 欧美一区二区免费| 久久一日本道色综合久久| 黄色成人av在线| 久久久噜噜噜久久中文字免| 玖玖玖国产精品| 亚洲人成在线观看网站高清| 欧美国产日产韩国视频| 亚洲日本va午夜在线电影| 99精品欧美一区二区三区| 欧美日韩精品三区| 国产精品99久久久久久久vr | 久久黄色小说| 国产一区二区黄| 久久精品国产久精国产爱| 欧美jizz19性欧美| 一本久道久久综合中文字幕 | 日韩午夜中文字幕| 欧美三级网址| 香蕉成人伊视频在线观看| 久久综合伊人77777麻豆| 精品成人a区在线观看| 欧美多人爱爱视频网站| 亚洲最新视频在线| 久久国产精品久久久久久| 有码中文亚洲精品| 欧美噜噜久久久xxx| 亚洲免费视频中文字幕| 卡通动漫国产精品| 亚洲少妇最新在线视频| 国产亚洲免费的视频看| 男男成人高潮片免费网站| 亚洲日本中文字幕免费在线不卡| 亚洲一区二区在线看| 国产自产精品| 欧美成人一区二区| 亚洲综合色激情五月| 欧美高清视频| 久久精品国产96久久久香蕉| 国产视频亚洲精品| 亚洲春色另类小说| 久久看片网站| 玉米视频成人免费看| 欧美+亚洲+精品+三区| 老司机午夜精品视频| 欧美一级二级三级蜜桃| 亚洲男人第一av网站| 欧美日本韩国一区| 麻豆精品视频在线观看视频| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲国产日本| 午夜伦理片一区| 亚洲影音先锋| 国产精品igao视频网网址不卡日韩| 久久成人精品无人区| 欧美日韩日日夜夜| 亚洲精品欧美极品| 亚洲乱码久久| 欧美人与禽猛交乱配| 亚洲精品中文字幕女同| 亚洲乱码国产乱码精品精可以看| 美女图片一区二区| 亚洲区一区二|