28 сентября 2010

Продвижения.

В общем, дела движутся. И сегодня решил рассказать про всякие технические подробности последних изменений. Вообще, код я стараюсь особо не трогать, чтобы ничего не испортить, но в последнее время без этого никак, так как баги и фичи касаются именно движковой части. Начну с того, что я получил баг-репорт из 30 пунктов, который мне сначала показался не очень сложным. Вернее, я сразу разделил баги на простые и сложные. Думал, с простыми разберусь быстро, а со сложными "что-нибудь придумаю". В этом сообщении решил немного рассказать про определенные баги, с которыми было интересно бороться. Некоторые из них решились изменением пары строк кода, некоторые - не решены до сих пор. В общем, надеюсь, что будет интересно. Для тех, у кого мало свободного времени, напишу краткий список багов:
  • Недопущение запуска второй копии программы
  • Падает под гостевым аккаунтом
  • Неверное поведение программы при нажатии кнопки "Переключиться" из диспетчера задач
  • Навигация по меню без фокуса в программе
  • Артефакты в изображении на нетбуке

Из названий багов видно, что второй и четвертый в списке - простые баги логики программы. Я их включил в сообщение, чтобы немного развеселить читателя, дать отдохнуть и сделать перерыв между описанием серьезных багов.
Баг -1. Недопущение запуска второй копии программ. Смысл такой: если программа уже запущена и мы пытаемся запустить вторую копию - блокировать запуск и активизировать первую копию. Прочитал описание баги и сразу подумал - да в Интернет полным полно исходников по этому поводу! Правда до этого момента необходимости в сохранении только одной запущенной копии программы у меня не было. В общем, начал читать, изучать. Наткнулся на этот форум, где приводят пример с использованием FindWindow() для посылки сообщения. Сразу не понравилось - хэндл выдастся только первого окна, что плохо. Да и по caption'у искать - это криво и неверно. На королевстве тоже наткнулся на статью, но как-то про почтовые ящики я слыхом не слыхивал, потому решил не использовать подобные методы. А почитав вот это, я совсем разочаровался в FindWindow и подобных методах. В общем, из этих всех источников становится ясным одно: нужно использовать объект ядра системы. Погуглив, сразу наткнулся на пример с исходными кодами. Радости моей не было предела - все заработало с первого раза, в delphi... а вот lazarus напрочь отказался компилироваться, указывая на то, что не существует свойства Application.Handle, чему я был очень недоволен. Как быть? Пришлось разнести момент записи в объект ядра Application.MainForm.Handle, и вызов функции FirstHinstanceRunning(), оставив в глобальной переменной значение MemHnd. Работает и в delphi, и в lazarus'е! Ура, как говорится!
Баг-2. Падает под гостевым аккаунтом. Когда я это прочитал, то в голове пробежали недобрые мысли. Затем я добавил нового юзера на свой компьютер с загадочным ником "Гость" и начал компилить программу, что оказалось не таким тривиальным делом - Гостю разрешается записывать только в My documents папку, даже настройки проекта не сохранить, даже dcu-шку не записать в положенное место. Но ничего, пути настроил, скомпилился, дебажу... и что я вижу? при записи программой в папку \All users\Application Data программа валится. Почему? Ну как бы гостю не положено изменять файлы, созданные другими пользователями. То есть, как я понял, если бы программа первый раз запустилась под гостем - то все было бы нормально, она работала бы и в гостевом юзере и под администратором. А наоборот - падает, выводя AV. Что делать? Ну, записывать в папку \My user\Application Data, а не в общие. Правда, я сначала негодовал, что я играю под одним юзером, потом захожу под другим - а профиля в игре нет, куда подевался? Да просто из другой папки теперь грузит. А потом мне сказали: "а вот мне было бы неприятно, если бы Гость мог под моим профилем играть, а того хуже - удалить". И тут меня осенило - точно! От сердца отлегло, и теперь программа с радостью пишет под каждым юзером в свою папку, не падает, веселится, играется. Вот такой глупый баг.
Баг-3. Неверное поведение программы при нажатии кнопки "Переключиться" из диспетчера задач. Я его уже описывал в предыдущих сообщениях, но, повторюсь, баг выглядит так:
1. загружаем программу, сворачиваем ее в панель задач
2. открываем диспетчер задач
3. находим в диспетчере наше приложение, нажимаем "Переключиться"
4. ловим баг - диспетчер сворачивается, а вот программа так и осталась свернутой в панели задач
 Я даже создал тему на форуме, чтобы найти решение. Правда помощи особой не нашлось. Вообще, сначала я начал крутить-вертеть различные события формы, смотреть, что происходит. В итоге добрался до того, что вроде как это и не баг. Дело вот в чем. При деактивации фуллскрин-программы, она автоматически сворачивается. Итак, что делает наш windows, при нажатии "переключиться"? Сначала разворачивается программа, и только потом сворачивается диспетчер. А что происходит при сворачивании диспетчера задач? Правильно, его окно активируется!.. а моя программа деактивируется... и сворачивается как и положено, думая, что нажали что-то вроде alt+tab. Как побороть эту ситуацию пока не знаю. Позапускал несколько казуальных игр, что у меня были на компьютере ("Космотанк", "Магазин тропических рыбок", "The Crop Circles Mystery") - у всех присутствует точно такой же баг. Скачал топовые игры ("Гиблые земли", "Остров секретов") - все работает как надо, никаких багов, видимо их двиги уже заточены под такие выкрутасы. Жаль, что этих разработчиков не знаю - спросить-то и не у кого, как побороть проблему. В общем, пока отложил эту задачу.
Баг -4. Навигация по меню без фокуса в программе. Для отдыха распишу этот забавный баг. Оказывается даже в свернутом состоянии программа в меню нажимала свои кнопки. Из-за этого можно было творить чуда - профили менять, громкость убавлять, даже при свернутом окне. Мистика! В общем, одно условие (Application.Active and Application.MainForm.Visible) все исправило...
Баг - 5. Артефакты в изображении на нетбуке. Ох, а вот это дело доставило мне массу неприятностей. Придется переписать довольно много кода. Для разрешения проблемы я так же запостил на форуме. В общем, проблема оказалась странной. Во-первых, при разрешении текстуры 1024х1024 и больше наблюдаются артефакты. Уменьшение размеров все исправляет. Но для бэков не получится довольствоваться жалкими 512х512 - смотрится убого! Для эффектов (пар, взрыв, дым, магические частицы и др.) тоже используются довольно большие атласы. Что делать? Повезло, что я случайно потыкал параметр компрессии на текстурах. Оказалось, что при выставленной компрессии артефактов не наблюдается. В итоге решил все эффекты использовать с включенной компрессией, а бэки собирать из 4ех текстур, натянутых на 4 спрайта (ирония, чтоб ее, сначала переписывал все под атласы, а теперь наоборот разрезаю картинки на меньшие). Пока полностью не доделал - как-то настроения нет, но вроде должно сработать. Нетбука теперь под рукой не будет, так что нужно будет все сделать аккуратно и точно. Вообще, затачивание программы под "старые" и "не игровые" системы - довольно интересное занятие: подбираешь параметры, оптимизируешь графику, отказываешься от частиц, улучшаешь систему физики и т.д.
Вот такой мини-отчет по пяти багам получился. Надеюсь было интересно.

Сообщения, схожие по тематике:

2 коммент.:

  1. баг-2: правильно, кэп, надо было сразу так делать!
    а так, вообще, пишешь серьёзное приложение - правь серьёзные баги. почему-то я тебе не завидую

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

    ОтветитьУдалить