Если я правильно понял, это обозначение последовательности отрисовки деталей или нет?
А вот на такие вопросы уже и не грех ответить.
Да, это список указателей на визуальные элементы. Используется симом в процессе обхода дерева приборов и их визуальных элементов. В каждом визуальном элементе есть указатель на next список визуальных элементов. Собственно из таких списков (в виде инициализированного статического массива, оканчивающегося элементом NULL) и строится дерево приборов и их визуальных элементов в dll (в gau). Ну и соответственно это дерево строится gau-писателем ведь не просто так. Именно через него сим осуществляет доступ к каждому визуальному элементу при прорисовке и именно имея указатели на приборы и их визуальные элементы сим 18 раз в секунду вызывает CallBack-функции всех приборов и визуальных элементов, если конечно они определены.
Важный момент.
Правильное построение дерева приборов и их визуальных элементов имеет очень важное значение (вернее будет — правильное построение поддеревьев (сучьев, веток, листьев), визуальных элементов в каждом приборе). Но это уже другая тема.
Почему именно дерево?
Потому, что это действительно дерево.
Корень вот:
// This is the module's export table.
GAUGESLINKAGE Linkage =
{
0x00000013,
module_init,
module_deinit,
0,
0,
0x800,
{
GAUGE_TABLE_ENTRY(&gaugehdr_isd1)
GAUGE_TABLE_ENTRY(&gaugehdr_isd2)
GAUGE_TABLE_ENTRY(&gaugehdr_kurs_mp_selekt)
....
Корень — структура Linkage. Далее список сучьев — приборов (после после 0x800). Ну а далее в каждом приборе, ветвление визуальных элементов.
Edited by serg_p
seycovip3029
21.10.2012 в 09:31
Спасибо Сергей за ответы, сорри, если не совсем точно могу задать свой вопрос.
Это определение статической переменной, которая тут же и инициализируется. Т.к. tank_2_list_2[] — это массив, то инициализация здесь производится не одним значением, а списком значений. NULL — это тоже значение. По этому значению симулятор определяет, что это конец массива. Стандартная практика в C.
{(PELEMENT_HEADER)&tank_2_03, NULL};
и
{&tank_2_03.header, NULL};
Это одно и тоже, за исключением того, что в верхней строке — явное приведение типа указателя, это хорошая практика, приведение типов осуществлять самому, т.е. явно. & — операция взятия адреса.
Здесь я просто засомневался в синтаксисе, для чего эти строки я прекрасно понимаю.
На эту книгу я наткнулся, введя сейчас в гугле: «книга C++ элементарные понятия».
Спасибо за ссылку, большой объем информации, самый полный для меня на сегодня.
Для меня интернет — огромная помойка, думаю не только для меня, и когда ищешь то, что тебе нужно, обязательно вылезет куча хлама, а в нём найти что-то нужное весьма затруднительно.
Вот то, что я читал и практиковал, может кому сгодится:
Естественно нигде нет полной информации для самостоятельного нормального обучения. Не думайте, что я «халявщик» и ничего не делаю для изучения. Для правильной обработки полученной информации нужен опыт в работе С++, просто примеры — этого мало. Нужен контроль, хоть какой-то. А то понял не совсем так и потом понеслось… Да и память у человека не компьютерная. Для переваривания каши в голове — практика, практика и еще раз практика. Появляются знания, появляются вопросы… Почитаешь форумы по С++, иногда волосы дыбом, хоть бы раз попал на форумы, где могут грамотно дать ответ на конкретный вопрос, а то и вовсе отправляют книги читать. Вот и приходится спрашивать тонкости для меня, для вас профи — элементарщина.
Edited by seyco
serg_p591
21.10.2012 в 09:44
Ну да, соглашусь, в русском инете — сплошные какие-то ублюдки. Неужели человечество вымерает?
(Хотя, кое-где встречаются люди, из-за которых еще теплится свет.)
Хорошая книга — вот верный друг. И лучше в твердой копии.
Конечно вопрос, где найти.
Но, как ни странно, этот сраный тырнет может в этом помочь.
Правда тут есть одна трудность. Если ты еще слаб в теме, то трудно определиться с тем, что именно тебе подходит. Тут конечно очень могут помочь советы тех кто знает. Но можно и самому наткнуться на стоящее. Так бывает. У меня не раз было. Я очень желал хорошую книгу по интересующей теме и она находилась.
До определенного времени для меня Windows API был темный лес.
Пока мне не посоветовали почитать:
Джеффри РИХТЕР, Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows
(Два издания этой книги я скачал из интернета)
Я бы этому человеку крепко пожал бы руку, ели бы довелось встретится.
По поводу програмирования для сима, Андрей icebear в свое время говорит про книгу Грифитcа (не знаю, правильно ли я пишу имя). То же, как я понял из его слов очень полезная книга для программистов работающих с симом.
Кажется тут видел не раз самого Доусона (того, кто написал фсупик)
Наверное еще есть сайты. Не раз натыкался на интересные вещи работая с поиском в гугле.
Единственное — они все на английском.
Ну и некоторые вещи (причем, думаю что важные) можно найти здесь.
Если вспомню или наткнусь на полезные книги — обязательно напишу.
Edited by serg_p
FortRoss8
08.11.2012 в 07:22
коммент по поводу очередности загрузки — с SimConnect может взаимодействовать и «приборная» dll, запись для нее в конфиге коннекта не нужна, записи в конфиге коннекта нужны для внешних библиотек, которые будет грузить сам коннект. Загружена же приборная dll будет при загрузке модели, тогда же будет дернут ее module_init, в котором и надо проинициализировать интерфейс с коннектом. Так что невидимый прибор — лишняя сущность
serg_p591
08.11.2012 в 14:27
Денис, Вы, похоже, имеете в виду случай, когда в dll есть видимые приборы и они прописаны в Panel.cfg. Тут да, сим загрузит dll, прочтет Linkage, выгребет из него указатель module_init() и запустит ее. Но ведь может быть так, что в данной dll нет ни одного видимого прибора, ну, например, просто не надо. В этом случае потребуется сделать один фейковый, невидимы прибор и писать его в Panel.cfg.
Т.е. тут собственно вопрос, откуда сим узнает, что нужно загрузить данную dll, если из нее в Panel.cfg, запускаемой модели не прописан ни один прибор и если данная dll не прописана в DLL.xml? Тут по-любому нужен либо один фейковый прибор, что бы сим загружал dll при загрузке полета с данной моделью, либо необходимо прописать dll в DLL.xml, что бы сим ее грузил при собственном старте. Я лично других вариантов не знаю и в SDK для FSX не видел. Мож пропустил.
А вариант, когда нет надобности делать в dll видимые приборы — реально возможен. Я сделал для Никиты (для Ту-144) dll, код которой читает некоторые L:переменные и пишет через SimConnect в переменные некоторых топливных баков и в некоторые Payload Stations (PAYLOAD STATION WEIGHT:index). Здесь потребовалось сделать один невидимый прибор и прописать его в Panel.cfg, что бы FSX загружал dll при старте полета с Ту-144. Собственно случай dll без единого видимого прибора вполне возможен и в серьезном приборном комплексе, когда весь уровень логики сконцентрирован в одной dll, а визуализация происходит исключительно в ВК через 3D приборы (собственно идеальный вариант ВК для самолетов с будильниками), ну или посредством XML приборов.
Edited by serg_p
seycovip3029
12.12.2012 в 07:21
День добрый. Для реализации множества систем ЛА потребовалось большое количество панелей (2D). В gauges.h и мануале SDK (Event IDs) нашел использование только 9ти панелей. Подскажите пожалуйста, если возможно, как открывать и закрывать панели с номером больше [Window08]?
И вот еще вопрос:
trigger_key_event (KEY_PANEL_1, 0); — с помощью этой команды происходит открытие / закрытие панели №1,
trigger_key_event (KEY_PANEL_ID_OPEN, 0); — а вот здесь не могу понять как открыть нужную панель?
fsfreelancer0
12.12.2012 в 10:31
День добрый. Для реализации множества систем ЛА потребовалось большое количество панелей (2D). В gauges.h и мануале SDK (Event IDs) нашел использование только 9ти панелей. Подскажите пожалуйста, если возможно, как открывать и закрывать панели с номером больше [Window08]?
И вот еще вопрос:
trigger_key_event (KEY_PANEL_1, 0); — с помощью этой команды происходит открытие / закрытие панели №1,
trigger_key_event (KEY_PANEL_ID_OPEN, 0); — а вот здесь не могу понять как открыть нужную панель?
в panel.cfg создаешь к примеру
[Window16]
Background_color=0,0,0
size_mm=690,276
visible=0
position=0
sizeable=1
ident=10016
gauge00=gauge!name, 0, 0
в гауге
#define IDENT_P16 (IDENT_USER+16)
panel_window_open_ident(IDENT_P16);
panel_window_close_ident(IDENT_P16);
Edited by fsfreelancer
seycovip3029
12.12.2012 в 16:55
в panel.cfg создаешь к примеру
[Window16]
Background_color=0,0,0
size_mm=690,276
visible=0
position=0
sizeable=1
ident=10016
gauge00=gauge!name, 0, 0
в гауге
#define IDENT_P16 (IDENT_USER+16)
panel_window_open_ident(IDENT_P16);
panel_window_close_ident(IDENT_P16);
Огромное спасибо, Работает! Теперь когда нет ограничений в окнах, можно в проект добавить много полезного… Например надпись «пауза» в середине экрана, когда пользователь ее жмет (не всегда сразу заметно дефолтную в углу экрана).
Edited by seyco
fsfreelancer0
12.12.2012 в 17:11
Огромное спасибо, Работает! Теперь когда нет ограничений в окнах, можно в проект добавить много полезного… Например надпись «пауза» в середине экрана, когда пользователь ее жмет (не всегда сразу заметно дефолтную в углу экрана).
ага. главное не забудь ident менять в окнах, пользовательские начинаются с 10000. и еще помоему есть какое-то ограничение на количество этих окон. количество не скажу, не помню.
icebear
04.02.2014 в 08:33
Ох, а что ж всё так сложно? Я так понимаю Вы пытаетесь при запуске подтянуть все файлы из какой-то конкретной sound директории? А зачем? Начните с малого, напишите инициализацию DX и чтение файлов из конктретной директории. Код уже есть. Я, к сожалению, с десяткой знаком поверхностно, но инициализация гауг там аналогична девятке, поэтому советую Вам обратить внимание на функции module_init и module_deinit, в них Вам и надо инициализировать/деинициализировать DX (для этого так же надо будет поковырять Linkage модуля, но это здесь уже обсуждалось тыщу раз). Далее, загружать все файлы сразу я бы не стал, я бы загрузку сделал on demand, т.е. если файл нужен — загрузили, оставили его в списке и делаем с ним всё что надо. Если какой-либо файл никогда не проиграется, то и в памяти ему делать нечего. Приведи пример из нашего тамагочи, надеюсь поможет:
Смысл всего этого в том, что есть класс CSoundFile, который оборачивает один конкретный wav файл. И есть менеджер класс, отвечающий за инициализацию и использование DirectSound. Загрузка и использование файла идёт через CSoundFile::LoadFile
Учтите, это всё для девятки (это важно для инициализации, под десятку возможно надо будет малость подправить). И ессно там только те функции, которые нужны были мне для тамагочи, DirectSound может намного больше. Например я сделал у нас адаптацию громкости звука в зависимости от положения наблюдателя (ВСУ например в кабине и ВК еле слышно, а при виде снаружи громкость обычная).
Flanker_AleX
05.02.2014 в 03:57
Мои под утренние отчёты становятся традицией )
Огромное спасибо за пример!
Почти во всём разобрался. Собрал библиотеку. «Щупом» MessageBox определил что пустой прибор, без .wav файлов, успешно загружается. MessageBox приветливо рапортует о том что wavefile == пуст. Как только прописываю путь к какому-нибудь звуковому файлу (к слову, я явно не так делаю, наверняка есть способ практичнее, попробую организовать запись в буфер из ресурса), предварительно вписав LoadFromFile метод в void FSAPI module_init(void) — FSX выдаёт фатальную ошибку. С чем это может быть связано?
Спасибо большое.
icebear
05.02.2014 в 08:27
Почти во всём разобрался. Собрал библиотеку. «Щупом» MessageBox определил что пустой прибор, без .wav файлов, успешно загружается. MessageBox приветливо рапортует о том что wavefile == пуст. Как только прописываю путь к какому-нибудь звуковому файлу (к слову, я явно не так делаю, наверняка есть способ практичнее, попробую организовать запись в буфер из ресурса), предварительно вписав LoadFromFile метод в void FSAPI module_init(void) — FSX выдаёт фатальную ошибку. С чем это может быть связано?
Спасибо большое.
Это надо в код гауги смотреть, так по фотографии я мало что могу определить. По поводу загрузки файла я свехру дал полностью рабочий код. Возьмите CSoundFile::LoadFromFile и сделайте как отдельную функцию. Не используйте ресурсы, хотя бы потому что потом у пользователей Вашей гауги будет возможность менять звуковые файлы (подходит для озвучки например). Да и от WAV файлов сам файл гауги распухнет. Ну это конечно всё если хранение звука в ресурсе не самоцель.
Ещё, как насчёт нормального дебагера вместо MessageBox? В десятке это также работает, как и в девятке, Вы же свою сборку делаете в дебаг версии? Тогда Вам ясно будет видно, где что валится.
И вообще где наши спецы по десятке? То их как песка в море, то все по окопам? Я не знаю, мож там какая особеность есть, которой нет в девятке.
Flanker_AleX
06.02.2014 в 00:39
Спасибо! По видимому, после ухода Сергея из FSX, специалистов 10-и не осталось. Ваш код я не трогал, оставил всё как есть, лишь вызов некоторых функций происходит через класс созданный по принципам описанным serg_p. Вот, к примеру, как выполнена тестовая загрузка файла:
К слову, достал обновлённую версию брошюры Dai Griffiths. По звуку там чуть-чуть, но есть пример использования DirectSound в приборах с исходным кодом. Так вот, тестовый прибор из примера, у меня отказался запускаться. Я начинаю думать, может у меня DirectX какой-то не такой =) !? 11 стоит.
Спасибо )
icebear
06.02.2014 в 08:38
Возможно что дело в версии DX, здесь у меня просто уже опыта не так много, как хотелось бы. Я так понимаю, у Вас SDK 11-й версии?
Почитайте вот это http://www.codeguru….DirectSound.htm , правда там малость другой подход.
Flanker_AleX
07.02.2014 в 00:31
Е-е-е-е-е! Заиграл родимый! =) icebear, спасибо большое.
Пользовался вот этим руководством, может кому-нибудь пригодится, там и исходные коды с примером есть.
Завтра всё причешу под FSX, пока есть затруднения с проигрыванием лишь при изменении значения переменной. Ни как не могу «проиграть» функцию без участия внутреннего таймера FSX.
Всем ещё раз большое спасибо!
icebear
07.02.2014 в 07:44
Ни как не могу «проиграть» функцию без участия внутреннего таймера FSX.
Это как понять? И ещё, Вы пишите гаугу «по старинке» или с симконнектом? Просто с симконнектом руки у Вас сильно развязаны и возможностей море.
Этот метод вызывается в секции PANEL_SERVICE_PRE_UPDATE основной функции прибора. К слову, изменения условия с рано на неравенство, проигрывание звука лишь инвертируется, т.е. заук играет либо когда генератор в положении 1, либо когда в положении 0. Не тогда когда он переходит с состояния 1 в состояние 0 — чего, собственно, я и пытаюсь добиться.
И ещё, Вы пишите гаугу «по старинке» или с симконнектом?
Всё организовано с помощью gauges.h, так как, на сколько я понял, SimConnect’а может быть целых три версии — отсюда могут возникнуть проблемы с совместимостью. И основное, мне в руке пока не попадались хоть какие-нибудь примеры динамических библиотек использующих исключительно SimConnect. Модули — да, но это не то.
Спасибо =)
UPD
Spoiler
void LogicType::update(void) // Make All Method
{
FLOAT64 gen_mast = 0;
execute_calculator_code ("(A:GENERAL ENG MASTER ALTERNATOR:1, Bool)", &gen_mast, NULL, NULL);
if(gen_mast == gen_mast_st)
{
m_Sound->PlayNow();
gen_mast_st = gen_mast;
}
}
Такой вариант так же не приводит к желаемому результату.
icebear
07.02.2014 в 13:57
«Не, ну в таких условиях я не могу работать»
Условие проигрывания отличается от того, что было пару сообщение назад. Вам нужна не простоя смена состояния, а конкретное, т.е. с одного конретного значение на другое. Попробуйте так:
Обратите внимание, присвоение идёт в каждой итерации цикла гауги, теперь оно вне скобок, это важный момент.
MrJam
28.04.2014 в 12:11
Люди добрые, подскажите кто сможите.
Остались ли тут грамотные специалисты по созданию приборов на с++? Есть некий проект. Но очень не хватает программеров. Если есть желание помочь, пишите в лс.
Krit
21.04.2015 в 05:00
Как лучше организовать обмен данными между С++ гагами в FSX?
Короче, указатели на структуры треба передавать в другую гагу.
Имхуется мне, разные гаги имеют разные адресные пространства и даже если напрямую передам указатель, н-р через XML-переменную, смысла не имеет.
Krit
22.04.2015 в 06:53
Это очень хорошо. Просто у Гриффитса написано в разделе «Runnig Visual C++ as a Gauge Debugger»:
This section has been deprecated as both FS9 and FSX will refuse to start if you attach a debugger to them. Microsoft giveth and Microsoft taketh away; they‟ve considerably improved the SDK for FS9 and FSX but have made it far more difficult to debug the gauges you create.
Вопрос по топливной системе: как добраться до баков EXTERNAL1 и EXTERNAL2 (FS9)?
Суть вопроса: для начала хочу просто считать количество топлива в баке (в Aircraft.cfg баки, естественно, заданы). Для всех остальных типов баков в GAUGES.H определены соответствующие токены, а для внешних — ничего не вижу. Токены FUEL_QUANTITY_RIGHT и FUEL_QUANTITY_LEFT показывают лишь суммы MAIN+AUX+TIP.
Поиск дал три зацепки:
1. Вот этот пост утверждает, что соответствующие токены ( A:FUEL TANK External1/External2 QUANTITY ) имеют место быть. И, действительно, в файле «FS2004_Value_Variables.txt» от http://www.FS2x.com такие токены есть. Более того, проверил в xml-приборе — токены работают. Но мне надо бы на С.
2. В модели Il-18 вроде бы реализован необходимый функционал. По крайней мере, соответствующий прибор панели показывает количество топлива в этих баках.
3. Токены определены и в SDK для АЫЧ. Но мне надо в FS9. Попытка самостоятельно прописать эти токены в GAUGES.H, естественно, успеха не имела.
Можно, конечно, пробовать извращаться с чтением токенов через L-переменные из xml-файла, но ведь должен быть более простой путь. Что и где я упустил?
Max999114
25.08.2017 в 08:31
Предыдущий вопрос порешил через дополнение GAUGES.H структурой XML_TOKEN. А вот как можно добраться до баков MAIN? В структуре FUEL_SELECT я этих баков не наблюдаю (видимо, кто-то в Microsoft решил «сэкономить» пару байтов). Пока могу добраться до них лишь опосредованно, через использование FUEL_TANK_SELECTOR_LEFT/RIGHT при уже пустых баках AUX и TIP. Но это явный костыль (к тому же, не везде работающий). Может, есть какой-то иной способ?
А вот на такие вопросы уже и не грех ответить.
Да, это список указателей на визуальные элементы. Используется симом в процессе обхода дерева приборов и их визуальных элементов. В каждом визуальном элементе есть указатель на next список визуальных элементов. Собственно из таких списков (в виде инициализированного статического массива, оканчивающегося элементом NULL) и строится дерево приборов и их визуальных элементов в dll (в gau). Ну и соответственно это дерево строится gau-писателем ведь не просто так. Именно через него сим осуществляет доступ к каждому визуальному элементу при прорисовке и именно имея указатели на приборы и их визуальные элементы сим 18 раз в секунду вызывает CallBack-функции всех приборов и визуальных элементов, если конечно они определены.
Важный момент.
Правильное построение дерева приборов и их визуальных элементов имеет очень важное значение (вернее будет — правильное построение поддеревьев (сучьев, веток, листьев), визуальных элементов в каждом приборе). Но это уже другая тема.
Почему именно дерево?
Потому, что это действительно дерево.
Корень вот:
// This is the module's export table. GAUGESLINKAGE Linkage = { 0x00000013, module_init, module_deinit, 0, 0, 0x800, { GAUGE_TABLE_ENTRY(&gaugehdr_isd1) GAUGE_TABLE_ENTRY(&gaugehdr_isd2) GAUGE_TABLE_ENTRY(&gaugehdr_kurs_mp_selekt) ....Корень — структура Linkage. Далее список сучьев — приборов (после после 0x800). Ну а далее в каждом приборе, ветвление визуальных элементов.
Edited by serg_p
Спасибо Сергей за ответы, сорри, если не совсем точно могу задать свой вопрос.
Здесь я просто засомневался в синтаксисе, для чего эти строки я прекрасно понимаю.
Спасибо за ссылку, большой объем информации, самый полный для меня на сегодня.
Для меня интернет — огромная помойка, думаю не только для меня, и когда ищешь то, что тебе нужно, обязательно вылезет куча хлама, а в нём найти что-то нужное весьма затруднительно.
Вот то, что я читал и практиковал, может кому сгодится:
http://shatalov.su/r…/cpp_primer.php
http://kvodo.ru/category/lessons
http://gendocs.ru/v3…33/лекции_по_cс
http://iguania.ru/
http://www.cppstudio…-vybora-if-else
Для подключения звука:
http://www.gamedev.r…/ds_usage_basic
http://exelab.ru/pro…=zart126<br />http://subscribe.ru/…54450.html#ds41
Естественно нигде нет полной информации для самостоятельного нормального обучения. Не думайте, что я «халявщик» и ничего не делаю для изучения. Для правильной обработки полученной информации нужен опыт в работе С++, просто примеры — этого мало. Нужен контроль, хоть какой-то. А то понял не совсем так и потом понеслось… Да и память у человека не компьютерная. Для переваривания каши в голове — практика, практика и еще раз практика. Появляются знания, появляются вопросы… Почитаешь форумы по С++, иногда волосы дыбом, хоть бы раз попал на форумы, где могут грамотно дать ответ на конкретный вопрос, а то и вовсе отправляют книги читать. Вот и приходится спрашивать тонкости для меня, для вас профи — элементарщина.
Edited by seyco
Ну да, соглашусь, в русском инете — сплошные какие-то ублюдки. Неужели человечество вымерает?
(Хотя, кое-где встречаются люди, из-за которых еще теплится свет.)
Хорошая книга — вот верный друг. И лучше в твердой копии.
Конечно вопрос, где найти.
Но, как ни странно, этот сраный тырнет может в этом помочь.
Правда тут есть одна трудность. Если ты еще слаб в теме, то трудно определиться с тем, что именно тебе подходит. Тут конечно очень могут помочь советы тех кто знает. Но можно и самому наткнуться на стоящее. Так бывает. У меня не раз было. Я очень желал хорошую книгу по интересующей теме и она находилась.
До определенного времени для меня Windows API был темный лес.
Пока мне не посоветовали почитать:
Джеффри РИХТЕР, Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows
(Два издания этой книги я скачал из интернета)
Я бы этому человеку крепко пожал бы руку, ели бы довелось встретится.
По поводу програмирования для сима, Андрей icebear в свое время говорит про книгу Грифитcа (не знаю, правильно ли я пишу имя). То же, как я понял из его слов очень полезная книга для программистов работающих с симом.
Еще есть сайт:
http://www.fsdeveloper.com/
Кажется тут видел не раз самого Доусона (того, кто написал фсупик)
Наверное еще есть сайты. Не раз натыкался на интересные вещи работая с поиском в гугле.
Единственное — они все на английском.
Ну и некоторые вещи (причем, думаю что важные) можно найти здесь.
Если вспомню или наткнусь на полезные книги — обязательно напишу.
Edited by serg_p
коммент по поводу очередности загрузки — с SimConnect может взаимодействовать и «приборная» dll, запись для нее в конфиге коннекта не нужна, записи в конфиге коннекта нужны для внешних библиотек, которые будет грузить сам коннект. Загружена же приборная dll будет при загрузке модели, тогда же будет дернут ее module_init, в котором и надо проинициализировать интерфейс с коннектом. Так что невидимый прибор — лишняя сущность
Денис, Вы, похоже, имеете в виду случай, когда в dll есть видимые приборы и они прописаны в Panel.cfg. Тут да, сим загрузит dll, прочтет Linkage, выгребет из него указатель module_init() и запустит ее. Но ведь может быть так, что в данной dll нет ни одного видимого прибора, ну, например, просто не надо. В этом случае потребуется сделать один фейковый, невидимы прибор и писать его в Panel.cfg.
Т.е. тут собственно вопрос, откуда сим узнает, что нужно загрузить данную dll, если из нее в Panel.cfg, запускаемой модели не прописан ни один прибор и если данная dll не прописана в DLL.xml? Тут по-любому нужен либо один фейковый прибор, что бы сим загружал dll при загрузке полета с данной моделью, либо необходимо прописать dll в DLL.xml, что бы сим ее грузил при собственном старте. Я лично других вариантов не знаю и в SDK для FSX не видел. Мож пропустил.
А вариант, когда нет надобности делать в dll видимые приборы — реально возможен. Я сделал для Никиты (для Ту-144) dll, код которой читает некоторые L:переменные и пишет через SimConnect в переменные некоторых топливных баков и в некоторые Payload Stations (PAYLOAD STATION WEIGHT:index). Здесь потребовалось сделать один невидимый прибор и прописать его в Panel.cfg, что бы FSX загружал dll при старте полета с Ту-144. Собственно случай dll без единого видимого прибора вполне возможен и в серьезном приборном комплексе, когда весь уровень логики сконцентрирован в одной dll, а визуализация происходит исключительно в ВК через 3D приборы (собственно идеальный вариант ВК для самолетов с будильниками), ну или посредством XML приборов.
Edited by serg_p
День добрый. Для реализации множества систем ЛА потребовалось большое количество панелей (2D). В gauges.h и мануале SDK (Event IDs) нашел использование только 9ти панелей. Подскажите пожалуйста, если возможно, как открывать и закрывать панели с номером больше [Window08]?
И вот еще вопрос:
trigger_key_event (KEY_PANEL_1, 0); — с помощью этой команды происходит открытие / закрытие панели №1,
trigger_key_event (KEY_PANEL_ID_OPEN, 0); — а вот здесь не могу понять как открыть нужную панель?
в panel.cfg создаешь к примеру
[Window16]
Background_color=0,0,0
size_mm=690,276
visible=0
position=0
sizeable=1
ident=10016
gauge00=gauge!name, 0, 0
в гауге
#define IDENT_P16 (IDENT_USER+16)
panel_window_open_ident(IDENT_P16);
panel_window_close_ident(IDENT_P16);
Edited by fsfreelancer
Огромное спасибо, Работает! Теперь когда нет ограничений в окнах, можно в проект добавить много полезного… Например надпись «пауза» в середине экрана, когда пользователь ее жмет (не всегда сразу заметно дефолтную в углу экрана).
Edited by seyco
ага. главное не забудь ident менять в окнах, пользовательские начинаются с 10000. и еще помоему есть какое-то ограничение на количество этих окон. количество не скажу, не помню.
Ох, а что ж всё так сложно? Я так понимаю Вы пытаетесь при запуске подтянуть все файлы из какой-то конкретной sound директории? А зачем? Начните с малого, напишите инициализацию DX и чтение файлов из конктретной директории. Код уже есть. Я, к сожалению, с десяткой знаком поверхностно, но инициализация гауг там аналогична девятке, поэтому советую Вам обратить внимание на функции module_init и module_deinit, в них Вам и надо инициализировать/деинициализировать DX (для этого так же надо будет поковырять Linkage модуля, но это здесь уже обсуждалось тыщу раз). Далее, загружать все файлы сразу я бы не стал, я бы загрузку сделал on demand, т.е. если файл нужен — загрузили, оставили его в списке и делаем с ним всё что надо. Если какой-либо файл никогда не проиграется, то и в памяти ему делать нечего. Приведи пример из нашего тамагочи, надеюсь поможет:
Инициализация интерфейса:
HWND hwndSim; HINSTANCE hInstanceSim; BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserve){ hwndSim = FindWindow(L"FS98MAIN", NULL); hInstanceSim = (HINSTANCE)hModule; return TRUE; } void FSAPI module_init(void){ soundResMgr = new CSoundResMgr(); if(!soundResMgr->Init(hwndSim)) MessageBox(NULL, L"Unable to initialize sound system", L"Tu2X4-Error", MB_OK); }Заголовок «библиотеки»:
#ifndef SOUND_RES_MGR #define SOUND_RES_MGR #include <dsound.h> #include <mmsystem.h> #define MIN_SOUND_VOL -10000 #define MAX_SOUND_VOL -3000 #define EXT_VIEW_VOL_DISP 3000 class CSoundResMgr { public: bool Init(HWND hWnd); void DeInit(); const HWND GetModuleWnd(){return hAirplaneWnd;} LPDIRECTSOUND GetDirectSoundInf(){return lpDirectSound;} protected: HWND hAirplaneWnd; LPDIRECTSOUND lpDirectSound; }; class CSoundFile{ public: CSoundFile(CSoundResMgr* soundresmgr){dsbSound = NULL;soundResMgr = soundresmgr;} ~CSoundFile(){if (dsbSound != NULL) { dsbSound->Release(); dsbSound = NULL; }} bool LoadFromFile(char* filename); void PlaySoundNow(bool looped = false); void StopSound(); void SetVolume(LONG volume); bool IsPlaying(); bool IsNearEnd(); protected: CSoundResMgr* soundResMgr; LPDIRECTSOUNDBUFFER dsbSound; DWORD soundCreationOptions; DWORD nearEndBorder; }; #endifКод «библиотеки»:
#include "SoundResMgr.h" bool CSoundResMgr::Init(HWND hWnd){ hAirplaneWnd = hWnd; if(DirectSoundCreate (NULL, &lpDirectSound, NULL) != DS_OK) return false; if(lpDirectSound->SetCooperativeLevel (hAirplaneWnd, DSSCL_NORMAL) != DS_OK) return false; return true; } void CSoundResMgr::DeInit(){ if (lpDirectSound) { lpDirectSound->Release(); lpDirectSound = NULL; } } bool CSoundFile::LoadFromFile(char* filename){ HMMIO wavefile; wavefile = mmioOpenA (filename, 0, MMIO_READ | MMIO_ALLOCBUF); if (wavefile == NULL) return false; soundCreationOptions = DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2; MMCKINFO parent; memset (&parent, 0, sizeof(MMCKINFO)); parent.fccType = mmioFOURCC ('W', 'A', 'V', 'E'); mmioDescend (wavefile, &parent, 0, MMIO_FINDRIFF); MMCKINFO child; memset (&child, 0, sizeof(MMCKINFO)); child.fccType = mmioFOURCC ('f', 'm', 't', ' '); mmioDescend (wavefile, &child, &parent, 0); WAVEFORMATEX wavefmt; mmioRead (wavefile, (char*)&wavefmt, sizeof(wavefmt)); if(wavefmt.wFormatTag != WAVE_FORMAT_PCM) return false; mmioAscend (wavefile, &child, 0); child.ckid = mmioFOURCC ('d', 'a', 't', 'a'); mmioDescend (wavefile, &child, &parent, MMIO_FINDCHUNK); //soundDuration = (DWORD)(1000 * child.cksize / wavefmt.nAvgBytesPerSec); nearEndBorder = child.cksize - (DWORD)(wavefmt.nAvgBytesPerSec*1.5); DSBUFFERDESC bufdesc; memset (&bufdesc, 0, sizeof(DSBUFFERDESC)); bufdesc.dwSize = sizeof(DSBUFFERDESC); bufdesc.dwFlags = soundCreationOptions; bufdesc.dwBufferBytes = child.cksize; bufdesc.lpwfxFormat = &wavefmt; if((soundResMgr!= NULL) && (soundResMgr->GetDirectSoundInf()->CreateSoundBuffer (&bufdesc, &dsbSound, NULL))!= DS_OK) return false; void *write1 = 0, *write2 = 0; unsigned long length1,length2; dsbSound->Lock (0, child.cksize, &write1, &length1, &write2, &length2, 0); if(write1 > 0) mmioRead (wavefile, (char*)write1, length1); if (write2 > 0) mmioRead (wavefile, (char*)write2, length2); dsbSound->Unlock (write1, length1, write2, length2); mmioClose (wavefile, 0); return true; } void CSoundFile::PlaySoundNow(bool looped){ DWORD dwLooping = looped ? DSBPLAY_LOOPING : 0; if(dsbSound){ if(!IsPlaying()){ dsbSound->SetCurrentPosition(0); dsbSound->Play(0, 0, dwLooping); } } } void CSoundFile::StopSound(){ if(dsbSound) dsbSound->Stop(); } void CSoundFile::SetVolume(LONG volume){ if((dsbSound) && (soundCreationOptions & DSBCAPS_CTRLVOLUME)){ if(volume < MIN_SOUND_VOL) dsbSound->SetVolume(MIN_SOUND_VOL); else if(volume > MAX_SOUND_VOL) dsbSound->SetVolume(MAX_SOUND_VOL); else dsbSound->SetVolume(volume); } } bool CSoundFile::IsPlaying(){ DWORD dwStatus = 0; bool isplaying = false; if(dsbSound){ dsbSound->GetStatus(&dwStatus); isplaying |= ( ( dwStatus & DSBSTATUS_PLAYING ) != 0 ); } return isplaying; } bool CSoundFile::IsNearEnd(){ bool isnearend = false; DWORD curPos = 0; if(dsbSound){ dsbSound->GetCurrentPosition(&curPos, NULL); if(curPos >= nearEndBorder) return true; } return isnearend; }Смысл всего этого в том, что есть класс CSoundFile, который оборачивает один конкретный wav файл. И есть менеджер класс, отвечающий за инициализацию и использование DirectSound. Загрузка и использование файла идёт через CSoundFile::LoadFile
Учтите, это всё для девятки (это важно для инициализации, под десятку возможно надо будет малость подправить). И ессно там только те функции, которые нужны были мне для тамагочи, DirectSound может намного больше. Например я сделал у нас адаптацию громкости звука в зависимости от положения наблюдателя (ВСУ например в кабине и ВК еле слышно, а при виде снаружи громкость обычная).
Мои под утренние отчёты становятся традицией )
Огромное спасибо за пример!
Почти во всём разобрался. Собрал библиотеку. «Щупом» MessageBox определил что пустой прибор, без .wav файлов, успешно загружается. MessageBox приветливо рапортует о том что wavefile == пуст. Как только прописываю путь к какому-нибудь звуковому файлу (к слову, я явно не так делаю, наверняка есть способ практичнее, попробую организовать запись в буфер из ресурса), предварительно вписав LoadFromFile метод в void FSAPI module_init(void) — FSX выдаёт фатальную ошибку. С чем это может быть связано?
Спасибо большое.
Это надо в код гауги смотреть, так по фотографии я мало что могу определить. По поводу загрузки файла я свехру дал полностью рабочий код. Возьмите CSoundFile::LoadFromFile и сделайте как отдельную функцию. Не используйте ресурсы, хотя бы потому что потом у пользователей Вашей гауги будет возможность менять звуковые файлы (подходит для озвучки например). Да и от WAV файлов сам файл гауги распухнет. Ну это конечно всё если хранение звука в ресурсе не самоцель.
Ещё, как насчёт нормального дебагера вместо MessageBox? В десятке это также работает, как и в девятке, Вы же свою сборку делаете в дебаг версии? Тогда Вам ясно будет видно, где что валится.
И вообще где наши спецы по десятке? То их как песка в море, то все по окопам? Я не знаю, мож там какая особеность есть, которой нет в девятке.
Ваш код я не трогал, оставил всё как есть, лишь вызов некоторых функций происходит через класс созданный по принципам описанным serg_p. Вот, к примеру, как выполнена тестовая загрузка файла:
void LogicType::init(void) //Class initialization method in void FSAPI module_init(void) { LPSTR testWav = "\test.wav"; testS.LoadFromFile(testWav); }А дебагером я проходил, только вот толку!? Ошибки я там не вижу.
Ругается так:
Тычет сюда
К слову, достал обновлённую версию брошюры Dai Griffiths. По звуку там чуть-чуть, но есть пример использования DirectSound в приборах с исходным кодом. Так вот, тестовый прибор из примера, у меня отказался запускаться.
Я начинаю думать, может у меня DirectX какой-то не такой =) !? 11 стоит.
Спасибо )
Почитайте вот это http://www.codeguru….DirectSound.htm , правда там малость другой подход.
Е-е-е-е-е! Заиграл родимый! =)
icebear, спасибо большое.
Пользовался вот этим руководством, может кому-нибудь пригодится, там и исходные коды с примером есть.
Завтра всё причешу под FSX, пока есть затруднения с проигрыванием лишь при изменении значения переменной. Ни как не могу «проиграть» функцию без участия внутреннего таймера FSX.
Всем ещё раз большое спасибо!
Это как понять? И ещё, Вы пишите гаугу «по старинке» или с симконнектом? Просто с симконнектом руки у Вас сильно развязаны и возможностей море.
В смысле делаю так:
Всё организовано с помощью gauges.h, так как, на сколько я понял, SimConnect’а может быть целых три версии — отсюда могут возникнуть проблемы с совместимостью. И основное, мне в руке пока не попадались хоть какие-нибудь примеры динамических библиотек использующих исключительно SimConnect. Модули — да, но это не то.
Спасибо =)
UPD
Такой вариант так же не приводит к желаемому результату.
Условие проигрывания отличается от того, что было пару сообщение назад. Вам нужна не простоя смена состояния, а конкретное, т.е. с одного конретного значение на другое. Попробуйте так:
if((gen_mast != gen_mast_st) && (gen_mast == 0)){
m_Sound->PlayNow();
}
gen_mast_st = gen_mast;
Обратите внимание, присвоение идёт в каждой итерации цикла гауги, теперь оно вне скобок, это важный момент.
Остались ли тут грамотные специалисты по созданию приборов на с++? Есть некий проект. Но очень не хватает программеров. Если есть желание помочь, пишите в лс.
Как лучше организовать обмен данными между С++ гагами в FSX?
Короче, указатели на структуры треба передавать в другую гагу.
Имхуется мне, разные гаги имеют разные адресные пространства и даже если напрямую передам указатель, н-р через XML-переменную, смысла не имеет.
Что за Гриффитс? Не гуглится.
Где это скачать можно?
Крайняя версия:
http://www.flightsim…archid=36032586
Не понял, пустая страница открывается:
Вопрос по топливной системе: как добраться до баков EXTERNAL1 и EXTERNAL2 (FS9)?
Суть вопроса: для начала хочу просто считать количество топлива в баке (в Aircraft.cfg баки, естественно, заданы). Для всех остальных типов баков в GAUGES.H определены соответствующие токены, а для внешних — ничего не вижу. Токены FUEL_QUANTITY_RIGHT и FUEL_QUANTITY_LEFT показывают лишь суммы MAIN+AUX+TIP.
Поиск дал три зацепки:
1. Вот этот пост утверждает, что соответствующие токены ( A:FUEL TANK External1/External2 QUANTITY ) имеют место быть. И, действительно, в файле «FS2004_Value_Variables.txt» от http://www.FS2x.com такие токены есть. Более того, проверил в xml-приборе — токены работают. Но мне надо бы на С.
2. В модели Il-18 вроде бы реализован необходимый функционал. По крайней мере, соответствующий прибор панели показывает количество топлива в этих баках.
3. Токены определены и в SDK для АЫЧ. Но мне надо в FS9. Попытка самостоятельно прописать эти токены в GAUGES.H, естественно, успеха не имела.
Можно, конечно, пробовать извращаться с чтением токенов через L-переменные из xml-файла, но ведь должен быть более простой путь. Что и где я упустил?
Предыдущий вопрос порешил через дополнение GAUGES.H структурой XML_TOKEN. А вот как можно добраться до баков MAIN? В структуре FUEL_SELECT я этих баков не наблюдаю (видимо, кто-то в Microsoft решил «сэкономить» пару байтов). Пока могу добраться до них лишь опосредованно, через использование FUEL_TANK_SELECTOR_LEFT/RIGHT при уже пустых баках AUX и TIP. Но это явный костыль (к тому же, не везде работающий). Может, есть какой-то иной способ?