Добавлено: Пн Авг 07, 2017 7:18
Заголовок сообщения:
Дело было так:
Запустил Эадор, и получил те самые дикие лаги. Погуглил, нашел этот форум, инфу про связь с частотой процессора.
Начал отлаживать в Ollydbg по функциям QueryPerformanceCounter, QueryPerformanceFrequency.
Потом нашел, скачал исходники Allegro (движок игры), вроде той же версии, что и dll в игре. В игре 4.3.1.0, а я скачал 4.3.10, т.к. 4.3.1.0 не было, подумал, что это одно и то же(чем оно и должно-бы было быть).
Покопавшись в исходниках, нашел проблемный код. Там проблема в коде таймеров. И есть 2 вида таймеров, выбирающиеся в зависимости от аппаратной поддержки(ну или как винда решит о её наличии). По умолчанию, более точный таймер, использующий зависящие от герцовки процессора QueryPerformanceCounter/Frequency. Думаю, сделаю просто, пусть будет таймер попроще, зато будет работать хорошо - пропатчу код выбора таймера.
Лажу, лажу в отладчике, смотрю, смотрю код, вижу что-то не сходится с исходниками, хотя должно. Не могу найти место выбора типа таймера.
Потом нашел в именованной экспортированной функции по именованным переменным тип таймера, так называемый timer_driver. Благо он dll экспортировался, так что было имя.
Смотрю, а у таймера в Эадоре совсем не тот ид, и не то описание, какие в исходниках! Покопался, покопался, и понял что у меня не тот код...
В общем перепробовал версий 6 или больше исходников, пока не нашел точно, которая была нужно в разделе unstable Sourceforge'a Allegro.
Оказывается 4.3.10 и 4.3.1.0, это, мать их, две разные версии! Ладно у них на сайте еще пишется, как 4.3.1 и 4.3.10, но всё равно, какого чёрта они нолик добавляют и думают что это хорошее версирование?
Покопался с правильными исходниками, через некоторое время нашел выбор типа таймера, зашитый в функции инициализации.
Пропатчил, и о чудо Эадор заработал без тормозов
Ну думаю, оно то неплохо, но надо бы по-хорошему найти баг и всё исправить в коде, и пересобрать Alleg_43.dll
Провозившись добрых 4-6 часов, таки заставил библиотеку собираться через MinGW.
Некоторое время покопался в коде, сначало думал проблема в расчётах интервалов времени, там множилось на 1 000 000 для конверсии из тиков в uSec и так далее.
Но нет, дело было не в этом.
Оказалось, что просто выдаваемая функцией обработки таймеров в цикл таймера задержка т.е. сколько циклу надо еще поспать, что не гонять процессор, получалась >1мс, и этот поток даст немного времени другим потокам.
Но вроде процессор же многоядерный, пусть себе жрёт на отдельном ядре, но почему-то это так не работает.
Ну вот вроде и всё. Фикс сработал, и всё заработало нормально
Только еще вылез вылет при выходе из игры, в destroy_display, не вдаваясь в глубину кода, просто добавил пару проверок на NULL в функцию destroy_bitmap, и всё стало хорошо.
Edit:
Пока печатал всё это, так ответ пришел
Оно может просто выбирать таймер низкого разрешения и тогда проблемы нет, зависит от системы, и может быть драйверов на чипсет.
У меня вообще по мифическим причинам QueryPerformanceFrequency возвращает 0 под Ollydbg второй версии, но не первой
Соответственно запускаешь под отладчиком, и проблема исчезает ха-ха