Jump to content
Sign in to follow this  
FortRoss

Вопросы по созданию приборов на С++

Recommended Posts

да особого смысла выносить в отдельные потоки нет, если только ты не считаешь всю динамику полностью. Ну и работа с недокументированностями фс9 и с коннектом - это немножко разные разности

Share this post


Link to post
Share on other sites

да особого смысла выносить в отдельные потоки нет, если только ты не считаешь всю динамику полностью. Ну и работа с недокументированностями фс9 и с коннектом - это немножко разные разности

 

ты шаман, тебе виднее :) просто у меня до сих пор шок от провала фпс в первой версии кпи, из-за которого у меня развилось маниакальное влечение к потокам, директиксу и т.п. и обязательно всё это в одну корзину :D вот кто-бы ещё время дал обо всём этом подумать....

undefined

Share this post


Link to post
Share on other sites

Вот собственно, что у меня получилось.

 

Прибор нужно прописать один раз, где-нибудь в Panel.cfg.

При инициализации загружается явным образом (с помощью LoadLibrary) SimConnect.dll для FSX SP1. Папка, откуда грузится SimConnect.dll должна лежать в рядом с этой dll. Можно положить, в какую-нибудь подпапку. Путь к подпапке прописан в paths.h.

 

Я упустил одну важную вещь, когда мы выше говорили про запуск логики. Кроме системного события "6Gz", в FSX есть еще событие "Frame". Как я понял, какие в данный момент FPS, с такой частотой и срабатывает это событие. Все хозяйство описано в sim.cpp. Update уровня логики запускается в SimConnectDispatchProc вот в этом месте:

 case SIMCONNECT_RECV_ID_EVENT_FRAME:
 {
  SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;
  switch(evt->uEventID)
  {
   // Notifications every visual frame. Срабатывает столько раз в секунду сколько FPS
   case cliEventFrame:
   {
 lookup_var(&simTick18);
 if (simTick18.var_value.n > tick18Prev)
 {
  // Вызываем обновление логики 18 раз в сеунду
  // Если EVENT_FRAME крутится быстрей 18гц - пропускаем эти события
  sim_LogicLevel->Update();
 }
 tick18Prev = simTick18.var_value.n;
   }
 break;
  }
 }
  break;

ps_tu144_various_20120120_1320.zip

Edited by serg_p
  • Upvote 1

Share this post


Link to post
Share on other sites

хм, пустой проект для сим коннекта. многие тут такое искали, спасибо

undefined

Share this post


Link to post
Share on other sites

Доброе время суток!

У меня вопрос к специалистам, в секции кода прибора, например стрелки:

 

...

MAKE_NEEDLE //

(

alt_needle,

BMP_ALT_NEEDLE,

&alt_list_5,

NULL,

IMAGE_USE_TRANSPARENCY|IMAGE_USE_ERASE|IMAGE_USE_LUMINOUS|IMAGE_HIDDEN,

0,

95, 108,

12, 70,

RADIO_HEIGHT,alt_needle_cb,

alt_nonlinearity,

3

)...

 

есть флаг IMAGE_HIDDEN, в сдк к сожалению только написано: "...не показывать это изображение до тех пор, пока код датчика конкретно не вызовёт его. Это динамически изменяется."

Подскажите плиз, кто знает, какой строкой "вызвать" изображение, я так понял это делается в секции колбэк. Спасибо за ответы.

  • Upvote 1
  • Downvote 1

Share this post


Link to post
Share on other sites

FLOAT64 FSAPI callback_function(PELEMENT_NEEDLE pelement)
{
   if ([некое условие])
   {
	 SHOW_IMAGE(pelement);
	 return [возвращаем нужное значение для управления битмапом];
   }
   else
   {
	 HIDE_IMAGE(pelement);
	 return 0.0; // например, 0, ну или другое значение, устанавливающее битмап в исходную позицию
   }
}

 

Сами макросы делают вот что:

SHOW_IMAGE(element):

element->image_flags &= ~IMAGE_HIDDEN

 

HIDE_IMAGE(element):

element->image_flags |= IMAGE_HIDDEN

 

Собственно это все в gauhes.h

 

По аналогии можете производить операции с другими флагами.

 

 

Важно!

Ни в коем случае не присваиваем флаг битовому полю image_flags.

Работаем исключительно с битвыми операциями:

| - для поднятия флага

и

обязательно сначала ~ к флагу, затем обязательно & с битовым полем и флагом - для сброса флага в 0.

Edited by serg_p
  • Upvote 1

Share this post


Link to post
Share on other sites

Спасибо большое! Сделал подсветку прибора от выключателя, со шкалой разобрался (с помощью MAKE_ICON, 0/-1)

, а со стрелкой - надеюсь с флагом должно получится...

 

Всё получилось, ещё раз спасиб.

Edited by seyco

Share this post


Link to post
Share on other sites

Сталкнулся еще вот с таким вопросом, в этой функции мне непонятно что означают названия условий:

 

void FSAPI sound_gau_cb ( PGAUGEHDR pgauge, int service_id, UINT32 extra_data )

{

switch(service_id)

{

case PANEL_SERVICE_CONNECT_TO_WINDOW: // extra_data = PANEL_WND

...

break;

case PANEL_SERVICE_PRE_INSTALL: // "install_routine()" // extra_data = resource_handle

...

break;

case PANEL_SERVICE_PRE_INITIALIZE: // "initialize_routine()"

...

break;

case PANEL_SERVICE_PRE_UPDATE: // "update_routine()"

...

break;

case PANEL_SERVICE_PRE_DRAW: // "draw_routine()"

...

break;

case PANEL_SERVICE_PRE_KILL: // "kill_routine()"

...

break;

}

}

 

Если кто знает подскажите пожалуйста или ссылочку киньте, где подсматреть можно...

И как правильно прописать вызов этой функции. Спасибо.

Edited by seyco

Share this post


Link to post
Share on other sites

Сталкнулся еще вот с таким вопросом, в этой функции мне непонятно что означают названия условий:

 

void FSAPI sound_gau_cb ( PGAUGEHDR pgauge, int service_id, UINT32 extra_data )

....

 

Если кто знает подскажите пожалуйста или ссылочку киньте, где подсматреть можно...

И как правильно прописать вызов этой функции. Спасибо.

 

Это стандартный gauge callback, прописывается в макросе инициализации гауги, который выглядит как

 

GAUGE_HEADER_FS800([GAUGE ID],[GAUGE_WIDTH],[GAUGE_NAME],&[GAUGE ELEMENT LIST],[GAUGE MOUSE RECT],sound_gau_cb,0,0)

 

Описание service_id найдёшь в gauges.h и книге Гриффитса (Creating C-Gauges.pdf, искать на авсимкоме).

 

 

И ещё: есть уже тема по созданию гауг на С, имеет смысл в неё писать http://www.avsim.su/forum/topic/85531-davayte-eshyo-raz-pogovrim-o-sozdanii-priborov-na-si/

Edited by icebear

Share this post


Link to post
Share on other sites

Спасибо большое! Останется еще разобраться, как лучше и проще организовать озвучку приборов... Кроме как с помощью Direct Sound вариантов пока не нашел, да и если честно, кроме документации (общего описания) в нете пока тоже ничего не нашел. В консольном окне делал, это просто, но не с помощью Direct Sound. А как в симулятор запихнуть..? Если есть у кого примеры, поделитесь пожалуйста, буду признателен.

Share this post


Link to post
Share on other sites

Спасибо большое! Останется еще разобраться, как лучше и проще организовать озвучку приборов... Кроме как с помощью Direct Sound вариантов пока не нашел, да и если честно, кроме документации (общего описания) в нете пока тоже ничего не нашел. В консольном окне делал, это просто, но не с помощью Direct Sound. А как в симулятор запихнуть..? Если есть у кого примеры, поделитесь пожалуйста, буду признателен.

 

В списке тем сверху есть тему по поводу озвучки их ХМЛ гауг, есть смысл её посмотреть, ибо л-переменные можно писать/читать в любых гаугах.

Share this post


Link to post
Share on other sites

В списке тем сверху есть тему по поводу озвучки их ХМЛ гауг, есть смысл её посмотреть, ибо л-переменные можно писать/читать в любых гаугах.

Спасиб, я не читал, не тратил драгоценное время, думал к С++ не подойдет...

Share this post


Link to post
Share on other sites

Спасиб, я не читал, не тратил драгоценное время, думал к С++ не подойдет...

 

Я вижу что и поиском не пользовался :) Всё-таки "раздобуть" книгу Гриффитса и прочитай хотя-бы её, там и про звуки есть.

Share this post


Link to post
Share on other sites

Поиском пользовался, но он зараза такую кучу выдает, можно ночь искать, голова кругом, уже было такое, Гриффитсона пытался найти, когда понял что она на инглишь, охота пропала, да и сылка попалась битая. У меня к сожалению с английским очень плохо, приходится сначала переводить, потом вникать... Пока повременю, очень интересно к моему первому прибору подключить звук.

Гриффитсона наконец скачал , уже легче :)

Edited by seyco

Share this post


Link to post
Share on other sites

Всем привет. Уже несколько дней и ночей потратил в поисках нужной информации, по поводу реализации звуков в кабине (для начала в консольной панели), но получается хожу вокруг да около, а цели добиться не могу. С++ начал изучать недавно, до этого работал в ассемблере (давно). Сделал свой первый прибор на С++ (радиовысотомер), подключил пока к 2м тумблерам - питание и подсветка приборов, завязал логику. Всё работает, теперь осталось разобраться, как подключить звук... Вот тут посыпались вопросы, которые разрешить сам не могу.

Хотелось реализовать задуманное с помощью Direct Sound и как можно проще, без наворотов, но чтоб несколько звуков можно было проиграть. Почитал статей кучу, собрал несколько примеров, там по одному звуку только, без буферов, скачал DS SDK8, наваротов... Наконец, нашел что-то похожее, на то, что мне нужно, а собрать до конца не могу (хотел для начала, чтоб в консоли проиграл звук, а как подключить нужный файл - торможу.

 

http://subscribe.ru/...54450.html#ds41

Здесь используются только базовые функции и интерфейсы, что сделает код независимым от версии DirectX !

 

#include <dsound.h>

#include <stdafx.h>

#include <Windows.h>

//#include <mmsystem.h>

 

int main ()

{

//идентификатор окна

HWND hWnd = NULL;

// Создаем объект аудиоустройства

HRESULT hRes;

LPDIRECTSOUND pDSound;

if (FAILED(hRes = DirectSoundCreate(NULL, &pDSound, NULL))) return hRes;

// Задаем модель взаимодействия (уровень привилегий обращения к звуковой аппаратуре)

// при воспроизведении звука с другими работающими приложениями, иначе вторичные буфера не будет микшироваться

if (FAILED(hRes = pDSound->SetCooperativeLevel(hWnd, DSSCL_NORMAL)))

return hRes;

// Далее приступим к созданию вторичного аудиобуфера. Для начала зададим его формат:

WAVEFORMATEX waveFmt;

waveFmt.wFormatTag = WAVE_FORMAT_PCM;

waveFmt.nChannels = 1;

waveFmt.nSamplesPerSec = 8000;

waveFmt.wBitsPerSample = 8;

waveFmt.nBlockAlign = (WORD)(waveFmt.wBitsPerSample * waveFmt.nChannels / 8);

waveFmt.nAvgBytesPerSec = waveFmt.nSamplesPerSec * waveFmt.nBlockAlign;

waveFmt.cbSize = 0;

// Далее следует заполнить структуру с информацией о создаваемом буфере. В данном случае

// мы создаем буфер с параметрами, описываемыми структурой waveFmt и размером, достаточным для размещения 4 с звука.

DSBUFFERDESC dsBufDesc;

ZeroMemory(&dsBufDesc, sizeof(dsBufDesc));

dsBufDesc.dwSize = sizeof(dsBufDesc);

dsBufDesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY;

dsBufDesc.dwBufferBytes = waveFmt.nAvgBytesPerSec * 4;

dsBufDesc.dwReserved = 0;

dsBufDesc.lpwfxFormat = &waveFmt;

// После этих подготовительных операций можно непосредственно создать сам буфер:

LPDIRECTSOUNDBUFFER pDsBuffer;

if (FAILED(hRes = pDSound->CreateSoundBuffer(&dsBufDesc, &pDsBuffer, NULL))) return hRes;

//И заполнить его данными:

if (FAILED(hRes = OnBufferLost(pDsBuffer, 440.0))) return hRes;

//Рассмотрим процедуру инициализации буфера данными на примере его восстановления:

HRESULT OnBufferLost(LPDIRECTSOUNDBUFFER lpDSBuffer, float flFreq )

{

HRESULT hRes;

PUCHAR pLockBuf;

DWORD dwBufSize;

WAVEFORMATEX waveFmt;

do hRes = lpDSBuffer->Restore();

while (hRes == DSERR_BUFFERLOST);

if ( FAILED( hRes )) return hRes;

if ( FAILED( hRes = lpDSBuffer->Lock(0, 0, (LPVOID*)&pLockBuf, &dwBufSize, NULL, 0, DSBLOCK_ENTIREBUFFER))) return hRes;

if ( FAILED( hRes = lpDSBuffer->GetFormat(&waveFmt, sizeof(waveFmt), NULL))) return hRes;

for (int i = 0; i < dwBufSize; ++i)

{

pLockBuf = (UCHAR)(64.0 * (1.0 + cos(2.0*3.1416*i*flFreq/waveFmt.nSamplesPerSec)));

}

return lpDSBuffer->Unlock( (LPVOID)pLockBuf, dwBufSize, NULL, 0);

}

// Механизм извещений

LPDIRECTSOUNDNOTIFY lpDsNotify;

DSBPOSITIONNOTIFY PositionNotify;

// Требуем нужный нам интерфейс IDirectSoundNotify

if (FAILED(hRes = pDsBuffer->QueryInterface(IID_IDirectSoundNotify,(LPVOID*)&lpDsNotify))) return hRes;

PositionNotify.dwOffset = DSBPN_OFFSETSTOP;

PositionNotify.hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);

hRes = lpDsNotify->SetNotificationPositions(1, &PositionNotify);

// Освобождаем не нужный более интерфейс

lpDsNotify->Release();

// А вот теперь можно и воспроизвести буфер:

while (pDsBuffer->Play(0, 0, 0 ) == DSERR_BUFFERLOST) OnBufferLost(pDsBuffer, 440.0);

// Ожидаем окончания воспроизведения буфера

WaitForSingleObject(PositionNotify.hEventNotify, INFINITE);

// По окончанию работы культурные люди прибирают за собой:

CloseHandle( PositionNotify.hEventNotify );

pDsBuffer->Release();

pDSound->Release();

// Воспроизведение нескольких буферов

//pDsBuffer_1 -> Play(0,0,0);

//pDsBuffer_2 -> Play();

//pDsBuffer_3 -> Play();

 

return 0;

}

 

В данный момент при компиляции возникает одна ошибка:

 

1>------ Построение начато: проект: 03, Конфигурация: Debug Win32 ------

1> 03.cpp

1>d:\документы\visual studio 2010\projects\03\03\03.cpp(24): error C2065: hWnd: необъявленный идентификатор

========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

 

Догадываюсь, наверное из-за отсутствия строк, где нужно добавить сам файл, могу ошибаться. Вытащить нужное из других готовых консольных примеров SDK не смог, везде своя лексика, мало опыту еще.

Остается просить опытных программистов помочь разобраться здесь или может кто подскажет, где найти похожий готовый пример для консоли, я даже не надеюсь о большем... (для сима).

Заранее благодарен.

 

 

Edited by seyco

Share this post


Link to post
Share on other sites

seyco

 

Вот выдрал из одного своего проекта.

 

DXUTsound.cpp + DXUTsound.h - классы оболчки для работы с DirectSound

 

play_sounds.cpp + play_sounds.h - определение проигрываемых звуков, общие функции управления звуками и функции уже прогрывания некоторых конкретных звуков. Последние, естественно, менять на свои. Или Удалить. Для проигрывания любого звука используется функция

SoundFilePlay(int sound_type, BOOL flag_looping, DWORD pos)

 

Первый параметр - номер звука из массива структур. Для прямого доступа лучше использовать именованные константы, определяемые в play_sounds.h в enum ids_sounds

Второй - флаг проигрывания по кругу

Третий - позиция с которой будет проигрываться звук, по умолчанию - 0

 

Уровень для каждого звука и путь получения его значения описывается в массиве структур.

 

естественно enum нужно привести в соответствие с массивом структур звуков.

 

В массиве структур - sounds описываются все звуки:

-Первое поле - обязательно NULL

-Второе - 0

-Третье - имя wav вайла. После к нему будет прибавлен путь до папки со звуками

-Четвертое - имя параметра в конфиге, для регулирования уровня данного звука. Можно иметь один параметр, но обязательно строку с его именем тогда задать для всех звуков.

-В последнем поле задается уровень от 0 до 100% по умолчанию.

 

В play_sounds.cpp

в стоках

sprintf_s(path_to_gau_cfg, "%s%s", path_to_sim, "gauges\\...\\....cfg");

...

sprintf_s(path_to_sound, MAX_PATH, "%s%s", path_to_sim, "gauges\\...\\...\\");

там где ... обязательно задать имена папок и файлов.

 

Вообще хранить файлы звуков в gauges не очень хорошо. Но так исторически сложилось в тех проектах, где я работаю.

Хранить все свое стоит в папке с моделью, т.е. где-то в ..\Aircraft\{папка самолета}\{например, в папке cfg_and_res}

Но тут, тогда нужно будет обязательно считать имя самолета из Aircraft и папку с самолетом называть именно так.

Другой вариант - хранить в определенной подпапке самолета и gau и уже получив, через функции API, полный путь к gau файлу, отсчитывать от него путь к конфигам и звукам.

 

Функция initialization_play_sounds() - должна обязательно вызываться в инициализации gau, т.е. в module_init

Функция deinitialization_play_sounds() - в module_deinit

 

Последние функции становятся доступными, если раскрыть макрос - GAUGE_TABLE_BEGIN()

 

В архиве есть папка libs

В ней заголовочный файл и lib из DirectX SDK 2007 для работы с DirectSound. (dxguid.lib - кажется не нужна)

После DirectX SDK 2007 уже DirectSound нет. Там уже другой, более крутой механизм проигрывания звуков.

Для сима вполне достаточно возможностей, которые предоставляет DirectSound из DirectX SDK 2007.

PlaySounds.zip

Edited by serg_p

Share this post


Link to post
Share on other sites

Я целей и задач не знаю, но может быть что-то попроще можно использовать? Например, winmm какойнить...

http://msdn.microsof...0(v=vs.85).aspx

PlaySoynd проигрывает файл, если я правильно понял. Мне нужно чтобы при загрузке самолета все используемые файлы писались в буферы, и там хранились до выхода из сима(самолета). Моё мнение это должно повысить производительность. Может я не прав, поправте меня, я ведь только учусь.

Share this post


Link to post
Share on other sites

В приведенном мной примере, как раз эти буферы и создаются в инициализации. В инициализации в них заливаются звуки из wav файлов и задается уровень громкости. Далее проигрывание производится уже загруженного звука. В деинициализации все удаляется.

Share this post


Link to post
Share on other sites

Вот выдрал из одного своего проекта.

 

 

 

Спасибо большое, очень выручили, я как раз и не хотел .dll загружать WAVE файлами. Я даже понять не смог в моем вареанте WAVE файл компилируется или просто считывается каждый раз при запуске самолета из директории. Теперь буду спокойно разбираться.

Edited by seyco

Share this post


Link to post
Share on other sites

В приведенном мной примере, как раз эти буферы и создаются в инициализации. В инициализации в них заливаются звуки из wav файлов и задается уровень громкости. Далее проигрывание производится уже загруженного звука. В деинициализации все удаляется.

 

Я уже понял, спабибо еще раз

Share this post


Link to post
Share on other sites

Мысли вслух:

1. А SetCooperativeLevel(NULL,) реально работает?

2. Не вижу ничего плохого в хранении звука как ресурса. Придется только написать собственную разборку RIFFа для получения WAVEFORMATEX и остального. Некоторые мысли по этому поводу есть в DX SDK

3. У меня в June 2010 DX SDK (Latest вроде как) DSound вполне наличествует

4. Если пишем звук под FSX - GUIDы надо брать из fsx.cfg

5. Опять же, если пишем под FSX - неплохо бы отработать кнопочку Mute

Share this post


Link to post
Share on other sites
... 1. А SetCooperativeLevel(NULL,) реально работает? ...

Это ты, я так понял, про код seyco?

HWND hWnd = NULL;
...
if (FAILED(hRes = pDSound->SetCooperativeLevel(hWnd, DSSCL_NORMAL)))
return hRes;

Тут да - нехорошо.

 

...

2. Не вижу ничего плохого в хранении звука как ресурса. Придется только написать собственную разборку RIFFа для получения WAVEFORMATEX и остального. Некоторые мысли по этому поводу есть в DX SDK ...

Если нужно заменить звук (на другой, ну мало ли, доработали вдруг), то что, будем компилить заново gau (dll)? Случай с reshack не рассматриваем, ибо если размер нового звука больше, воспользоваться reshack-ом нельзя. Да и думаю вообще, хранить данные и ресурсы в теле модуля - зло.

 

... 3. У меня в June 2010 DX SDK (Latest вроде как) DSound вполне наличествует ...

Точно помню, когда хотел найти dsound.h - не нашел его в June 2010 DX SDK. А в доке было написано, что XAudio2 заменил Direct Sound с , точно не помню, кажется с версии DX SDK 2008. Сейчас некогда ставить June 2010 DX SDK, но вот, например, сейчас наткнулся на статью:

 

Программирование звука с использованием XAudio2

Программирование звука с использованием XAudio2.

...

Введение

...

Как заявляет сама Microsoft (смотреть тут), она больше не поддерживает DirectSound, и новые проекты, в зависимости от типа, должны использовать новое программное обеспечение. Для игр это XAudio2 и X3DAudio, для всего остального — Windows Core Audio.

...

Edited by serg_p

Share this post


Link to post
Share on other sites

Игорь, а где ты это увидел?

Или ты про код seyco?

Именно там

 

Если нужно заменить звук (на другой, ну мало ли, доработали вдруг), то что, будем компилить заново gau (dll)? Случай с reshack не рассматриваем, ибо если размер нового звука больше, воспользоваться reshack-ом нельзя. Да и думаю вообще, хранить данные и ресурсы в теле модуля - зло.

Насчет замены - согласен, насчет зла - нет :)

 

 

Точно помню, когда хотел найти dsound.h - не нашел его в June 2010 DX SDK.

Вот сейчас посмотрел в свой DXSDK/Include - вот он, dsound.h, размером 113801 байт...

Share this post


Link to post
Share on other sites

Ну значит я ошибся.

Хотя, MS точно не рекомендовала использовать его. Этот текст на англицком я точно видел. Сейчас некогда искать.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...