Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Помогите расставить всё на свои места (2 стр)

Помогите расставить всё на свои места (2 стр)

Поделиться
Страницы: 1 2 3 Следующая »
ashujonПостоялецwww29 июня 201017:03#15
мне концепция ввода через winapi не нравится тем что порождает связь между системой ввода и окном =(, потому использую DirectInput
s3dworldПостоялецwww29 июня 201017:07#16
Woland
Так на сколько я знаю, в DirectMusic есть интерфейс IDirectMusicLoader8, который позволяет загружать с жёсткого диска, из ресурсов программы и Бог ещё знает от куда, WAV, MID и ещё какой-то формат звуковых файлов.
s3dworldПостоялецwww29 июня 201017:11#17
Я вот когда вчера написал ToneGenerator (по книжке), у меня, когда заканчивает играть буфер, то происходит звук такой, будто тут же напряжение поступило и ушло, как бы щелчок. А стоит проигрывание буфера по кругу до бесконечности. Что это вообще такое и как этого избежать? Вот исходный код примера:
#include <iostream>
#include <sstream>
#include <conio.h>
#include <string>
#include <math.h>
#include <Windows.h>
#include <dsound.h>

using namespace std;

#define PI 3.14159

IDirectSound8* sound=0;

int CreateSecondaryBuffer(IDirectSoundBuffer** buffer,int channels,int secs,int sampleRate,int bitSperSample,DWORD flags);
void FillBuffer(IDirectSoundBuffer* buffer,float frequency,int bufferStart,int bufferLen,int sampleRate);
void PlayBuffer(IDirectSoundBuffer* buffer);
void StopBuffer(IDirectSoundBuffer* buffer);

int main()
{
  IDirectSoundBuffer* primaryBuffer=0;
  IDirectSoundBuffer* secondaryBuffer=0;
  DSBUFFERDESC dsBufferDesc;
  WAVEFORMATEX waveFormat;
  int secondaryBufferSize=0;

  if(DirectSoundCreate8(0,&sound,0)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу создать DirectSound!","Ошибка!",MB_ICONERROR);
    return 1;
  }

  if(sound->SetCooperativeLevel(GetConsoleWindow(),DSSCL_PRIORITY)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу установить уровень взаимодействия DirectSound!","Ошибка!",MB_ICONERROR);
    return 1;
  }

  ZeroMemory(&dsBufferDesc,sizeof(DSBUFFERDESC));

  dsBufferDesc.dwSize    = sizeof(DSBUFFERDESC);
  dsBufferDesc.dwFlags  = DSBCAPS_PRIMARYBUFFER;

  if(sound->CreateSoundBuffer(&dsBufferDesc,&primaryBuffer,0)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу создать звуковой первичный буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return 1;
  }

  ZeroMemory(&waveFormat,sizeof(WAVEFORMATEX));

  waveFormat.wFormatTag    = WAVE_FORMAT_PCM;
  waveFormat.nChannels    = 2;
  waveFormat.nSamplesPerSec  = 22050;
  waveFormat.wBitsPerSample  = 16;
  waveFormat.nBlockAlign    = waveFormat.wBitsPerSample/8*waveFormat.nChannels;
  waveFormat.nAvgBytesPerSec  = waveFormat.nSamplesPerSec*waveFormat.nBlockAlign;
  waveFormat.cbSize      = sizeof(WAVEFORMATEX);

  if(primaryBuffer->SetFormat(&waveFormat)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу установить формат первичного буфера DirectSound!","Ошибка!",MB_ICONERROR);
    return 1;
  }

  if((secondaryBufferSize=CreateSecondaryBuffer(&secondaryBuffer,2,7,22050,16,0))==0)
  {
    return 1;
  }

  char text[10];

  cout<<"Hello!";

  int f=0;

  FillBuffer(secondaryBuffer,329.63,22050*0,22050,22050);
  f+=22050;
  FillBuffer(secondaryBuffer,0,f,45000,22050);
  f+=45000;

  FillBuffer(secondaryBuffer,329.63,f,22050,22050);
  f+=22050;
  FillBuffer(secondaryBuffer,0,f,45000,22050);
  f+=45000;

  FillBuffer(secondaryBuffer,329.63,f,15000,22050);
  f+=15000;
  FillBuffer(secondaryBuffer,0,f,15000,22050);
  f+=15000;

  FillBuffer(secondaryBuffer,329.63,f,25000,22050);
  f+=25000;
  FillBuffer(secondaryBuffer,0,f,30000,22050);
  f+=30000;

  FillBuffer(secondaryBuffer,392.00,f,22050,22050);
  f+=22050;
  FillBuffer(secondaryBuffer,0,f,30000,22050);
  f+=30000;

  FillBuffer(secondaryBuffer,369.99,f,15000,22050);
  f+=15000;
  FillBuffer(secondaryBuffer,0,f,15000,22050);
  f+=15000;

  FillBuffer(secondaryBuffer,369.99,f,15000,22050);
  f+=15000;
  FillBuffer(secondaryBuffer,0,f,35000,22050);
  f+=35000;

  FillBuffer(secondaryBuffer,329.63,f,15000,22050);
  f+=15000;
  FillBuffer(secondaryBuffer,0,f,15000,22050);
  f+=15000;

  FillBuffer(secondaryBuffer,329.63,f,18000,22050);
  f+=18000;
  FillBuffer(secondaryBuffer,0,f,30000,22050);
  f+=30000;

  FillBuffer(secondaryBuffer,329.63,f,15000,22050);
  f+=15000;
  FillBuffer(secondaryBuffer,0,f,15000,22050);
  f+=15000;

  FillBuffer(secondaryBuffer,329.63,f,25000,22050);
  f+=30000;
  FillBuffer(secondaryBuffer,0,f,25000,22050);
  f+=35000;

  FillBuffer(secondaryBuffer,0,f,secondaryBufferSize-f,22050);

  PlayBuffer(secondaryBuffer);

  cin>>text;

  if(secondaryBuffer)
  {
    secondaryBuffer->Release();
    secondaryBuffer=0;
  }

  if(primaryBuffer)
  {
    primaryBuffer->Release();
    primaryBuffer=0;
  }

  if(sound)
  {
    sound->Release();
    sound=0;
  }

  return 0;
}

// Создание вторичного буфера
int CreateSecondaryBuffer(IDirectSoundBuffer** buffer,int channels,int secs,int sampleRate,int bitSperSample,DWORD flags)
{
  DSBUFFERDESC dsBufferDesc;
  WAVEFORMATEX waveFormat;

  ZeroMemory(&waveFormat,sizeof(WAVEFORMATEX));

  waveFormat.wFormatTag    = WAVE_FORMAT_PCM;
  waveFormat.nChannels    = channels;
  waveFormat.nSamplesPerSec  = sampleRate;
  waveFormat.wBitsPerSample  = bitSperSample;
  waveFormat.nBlockAlign    = waveFormat.wBitsPerSample/8*waveFormat.nChannels;
  waveFormat.nAvgBytesPerSec  = waveFormat.nSamplesPerSec*waveFormat.nBlockAlign;
  waveFormat.cbSize      = sizeof(WAVEFORMATEX);

  ZeroMemory(&dsBufferDesc,sizeof(DSBUFFERDESC));

  dsBufferDesc.dwSize        = sizeof(DSBUFFERDESC);
  dsBufferDesc.dwFlags      = flags;
  dsBufferDesc.dwBufferBytes    = sampleRate*bitSperSample/8*channels*secs;
  dsBufferDesc.guid3DAlgorithm  = GUID_NULL;
  dsBufferDesc.lpwfxFormat    = &waveFormat;

  if(sound->CreateSoundBuffer(&dsBufferDesc,&*buffer,0)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу создать звуковой вторичный буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return 0;
  }

  return dsBufferDesc.dwBufferBytes;
}

// Заполнение буфера
void FillBuffer(IDirectSoundBuffer* buffer,float frequency,int bufferStart,int bufferLen,int sampleRate)
{
  unsigned char* pBufferBytes;
  DWORD lockedSize;
  DWORD q;
  float pos;
  float r;
  float value;

  if(buffer->Lock(bufferStart,bufferLen,(void**)(&pBufferBytes),&lockedSize,0,0,0)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу заблокировать вторичный буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return;
  }

  for(q=0;q<lockedSize;q++)
  {
    pos=frequency/(float)sampleRate*(float)q;
    r=(pos-floor(pos))*2*PI;
    value=sin(r);
    pBufferBytes[q]=127+(value*127);
  }

  if(buffer->Unlock(pBufferBytes,lockedSize,0,0)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу разблокировать вторичный буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return;
  }
}

// Проигрывание буфера
void PlayBuffer(IDirectSoundBuffer* buffer)
{
  if(buffer->Play(0,0,DSBPLAY_LOOPING)!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу проиграть вторичный буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return;
  }
}

// Остановка проигрывания буфера
void StopBuffer(IDirectSoundBuffer* buffer)
{
  if(buffer->Stop()!=DS_OK)
  {
    MessageBoxA(GetConsoleWindow(),"Не могу остановить проигрывание вторичного буфер DirectSound!","Ошибка!",MB_ICONERROR);
    return;
  }
}
nov09Постоялецwww29 июня 201017:28#18
s3dworld
> С помощью Win32 API .... А вот с тем же колёсиком не работал
Я работал с колёсиком в Win32 API, всё работает.
WolandПостоялецwww29 июня 201017:34#19
Дык с колесом оно работать будет. Обычные оконные приложения прекрасно с ним работают, не думаю, что они юзают DI. Другое дело, если на какой-нибудь геймерской мыши этих колесиков множество и хочется их использовать или вообще нужно подключить джойстик - DI делает это не то, чтобы совсем красиво, но достаточно прозрачно. Кроме того, на сколько мне известно, WinAPI позволяет обрабатывать ограниченное количество одновременно нажатых клавиш, а это для игры уже существенный минус.
Для простой игры, не предполагающей использования сложных аккордов WinAPI конечно можно использовать.
s3dworldПостоялецwww29 июня 201017:39#20
Woland
Это ты хочешь сказать что в некоторых играх, когда играешь на одном компьютере вдвоём, то может получиться так, что первый игрок будет идти вверх-влево и стрелять (то есть нажмёт три клавиши), а второй игрок если нажмёт идти вправо, то вправо и пойдёт, но уже при нажатии на кнопку стрелять - он не будет стрелять, так как игра написана на Win32 API и не позволяет обрабатывать множество нажатий кнопок? Я всю жизнь думал это архитектура клавиатуры не позволяет обрабатывать одновременно множество кнопок.
slava_mibМодераторwww29 июня 201017:52#21
s3dworld, ты хотя бы читай что тебе пишут )))))
тебе:
>если на какой-нибудь геймерской мыши этих колесиков множество
ты:
>Я всю жизнь думал это архитектура клавиатуры

rofl

s3dworldПостоялецwww29 июня 201017:55#22
slava_mib
Это ты читай. Я говорю в данном случае именно про клавиатуру.
slava_mibМодераторwww29 июня 201018:01#23
s3dworld, в данном случае, как и всегда, ты просто несёшь какую-то чушь, суть которой уловить довольно сложно.

Не нравится DI - не юзай, нравится - юзай. Аналогично и со всем остальным.

О том, что какие-то компоненты больше не поддерживаются или когда-то перестанут поддерживаться - майкрософт пишет в КАЖДОМ выпуске хелпа по дх сдк. Хрен ли вот тут воду в ступе толочь, когда там всё чёрным по белому написано - что поддерживается, что изменилось, что сейчас тестируется, что скоро будет исключено, что уже исключено...

WolandПостоялецwww29 июня 201018:08#24
s3dworld
> Это ты хочешь сказать что в некоторых играх, когда играешь на одном компьютере
> вдвоём
В таких играх ввод на WinAPI не делают.
Клавиатура передает инфу обо всех нажатых/отжатых клавишах, а WinAPI обрабатывает столько, сколько может. DI общается напрямую с драйвером, поэтому ограничения эти ограничения для него идут лесом.
Инфа на самом деле не очень свежая, может в новых версиях винды что-то изменилось.
bashukinУдалёнwww29 июня 201018:44#25
Woland
>Клавиатура передает инфу обо всех нажатых/отжатых клавишах, а WinAPI обрабатывает столько, сколько может.
Это про сообщения? Но ведь помимо сообщений ведь есть GetAsyncKeyState?
WolandПостоялецwww29 июня 201019:00#26
bashukin
> Это про сообщения? Но ведь помимо сообщений ведь есть GetAsyncKeyState?
Ноги все оттуда же растут вроде.
X512Постоялецwww29 июня 201019:30#27
Woland
> Или я не прав?
Не прав. Даже джойстики через WinAPI прикрутить можно.
d.m.kУдалёнwww29 июня 201019:50#28
Откройте для себя WM_INPUT. На худой конец для других контроллеров по помимо мыши и клавы есть еще mmsystem (ныне в winmm.dll).  Я вообще никогда этот DI не использовал, а большинство игр которые его используют обладают диким лагом, особенно старые.

По поводу заеданий кнопок на клавиатуре - это дело не в венде, а в клавиатуре, дешевые клавы некоторые и по 4-то не всяких комбинации держат. Венда всегда обрабатывает все, до того момента, пока буфер не переполнится (начинает пищать при нажатии на клавиши). Переполнения в независшей программе врядли удастся добиться.

1 frag / 2 deathsУчастникwww29 июня 201020:27#29
Woland
> Кроме того, на сколько мне известно, WinAPI позволяет обрабатывать ограниченное
> количество одновременно нажатых клавиш

ЛОЛ.
Это из той же серии, что "Паскаль не позволяет записать что-то в защищённый адрес, такое может только Си Плюс Плюс."

Страницы: 1 2 3 Следующая »

/ Форум / Программирование игр / Общее

Тема в архиве.

2001—2017 © GameDev.ru — Разработка игр