Comments 20
Мощно.
А просто заменить Edit на Static?
Да, вы правы. Так буквы при печати не появляются. К сожалению слово STATIC длиннее и хуже жмется, но да - если хочется перфекционизма, это отличный шаг. Тем более - места теперь много. Я просто оставил то, что было изначально в коде.
Добавил в исходный код ваш вариант, для тех, кто будет читать.
Раньше всё это можно было искать в MSDN, а теперь приходится у чатботов, потому что нет больше подробного MSDN, остались куцые страницы.
Так вот, когда сел проверять, оказалось, что то ли SDK поменяли, то ли железного дурака заглючило, но в моём SDK (10.0.28000.0) WC_STATIC задан через суффикс W, а тот ведёт на L"Static", не на макрос. И значение константы 0x8003 тоже ошибочное. С ним окно не создаётся, а GetLastError() возвращает 1407 (Cannot find window class.)
Возможно, подход всё-таки рабочий, но не в таком виде, как написано ниже. Позже попробую разобраться, раз уж начал.
Было:
слово STATIC длиннее и хуже жмется
Передавайте вместо указателя на строку с оконным классом однословное целое (WORD). Из-за того, что второе слово нулевое, винды понимают, что это не настоящий указатель на строку. А то, что это одно слово, может быть, как-то поможет оптимизации.
WC_STATIC из <windows.h> определён как MAKEINTATOM(0x8003), а MAKEINTATOM как #define MAKEINTATOM(i) ((LPCTSTR)(((WORD)(i)))).
Так же и работа с ординалами, о которых вы пишете, устроена, насколько я помню. (Помню не очень уверенно). GetProcAddress тоже запросто кушает под видом lpsz просто число из нижнего диапазона.
Исследование показало, что метод вполне рабочий, но константы не документированы. В разных местах они описаны по-разному, поэтому попугая и глючит.
Вот такой код на Windows 11:
HWND hStatic = ::CreateWindow(
MAKEINTATOM(0xC01A),
NULL,
WS_CHILD | WS_VISIBLE | SS_RIGHT,
0,
0,
200,
24,
m_hWnd,
nullptr,
GetModuleHandleW(NULL),
NULL
);
DWORD dwError = ::GetLastError();
работает и даёт нам натуральный Static с SS_RIGHT (для контроля). Проверено Spy++.
Число 0xC01A подобрал методом тыка.
Забавно, что я когда я стал разбираться, откуда чатбот взял неправильные константы), то набрёл на вот этот багрепорт на WINE: https://bugs.winehq.org/show_bug.cgi?id=49195
Оказывается, это освящённая временем техника демосценеров: не использовать литералы для оконных классов.
Я нашел что на самом деле это 0xC019 - так что да - с этой константой оно сработало - но, к сожалению, все равно стало на 3 байта больше. Хотя и сама строка "EDIT" удалилась. Но в исходник я тоже добавлю.
Как я написал выше, число 0xC01A я подобрал методом тыка. Мне попалась таблица, где было указано, что Static это 0xC019. Я попробовал, но по факту создался Edit. Не только Spy++ его показал, но ещё и текст в него можно было вводить. Тогда я уменьшил значение на единицу и получил Button. Уменьшил ещё на единицу и получил 1407/Cannot find window class. Тогда я увеличил значение на единицу (до 0xC01A) и получил, наконец, Static.
А почему на три байта больше? Если в коде будет два байта константы вместо шести байт строкового литерала.
Внутри оказался OpenGL, причем самой базовой версии — то есть — без всяких там шейдеров
Для 2004-го года это обычное дело :)
ЗЫ: я так понимаю, реверс-инжениринг с помощью ИИ сделан? Я не осуждаю, если что :) А выпуск версий под современную Винду - так вообще одобряю!
Как вам сказать. ИИ использовалось, но исключительно для трех вещей:
1. Поиск информации об API. Я бы мог, например, и в гугле поискать параметры CreateWindowsEx и определить порядок PUSH'ей, но зачем если так будет быстрее
2. Поиск инфрормации о внешних инструментах, например, как запустить Crinkler и какие у него опции. Опять же - мог бы найти и сам, но быстрее
3. Информация о работе со звуком - так как я слабо представляю себе как всякие волны (которые я могу дизассемблировать) сливаются в гармонию. То есть - я понял весь код ассемблерного движка, но в мелодию в голове это не складывалось
А так - сам дизассемблинг и понимание текста - исключительно мое. Могу "пояснить" за каждый байт :)
Понятно. Прост сейчас, как вы наверное знаете, популярная тема - "декомпилировать" с помощью Claude старые демки и буквально портировать в wasm под браузер (попутно эмулируя железо). Об этичности и полезности чего ведутся горячие дебаты на pouet.net ;) Но помимо этого "нейронка" на раз делает и разбор внутреннего устройства демо, например https://claude.ai/artifact/HFgcoP4vY6ULruAVzEc9fg
В страшное время живём :)
К слову, KKrieger имхо бессмысленно ковырять и пытаться уменьшить. Во-первых он создан с помощью тулзы werkkzeug (и саунд-синта v2), код ее генераторов мешей, текстур и аудио-синтеза уже бешено оптимизирован (ведь Фарбы не одну 64кб-собаку на этом съели). Во-вторых exe-шник пожат их же передовым (на тот момент) пакером kkrunchy.
Даже если выгадать пару-тройку килобайт при компиляции - последующая упаковка нивелирует все старания. Упаковаться может даже хуже.
Тем интереснее же.
Пока чем больше я его ковыряю - тем больше вижу мест где можно все сократить - и вообще все не оптимально. Я понимаю что на 99% это потому что писалось на Си - и хоть и "достаточно оптимально", но это все равно не Ассемблер. Например первые же действия - создать "главный класс игры" в Си записалось как "выделить 3 мегабайта памяти под класс, получить указатель на него, вызвать одну функцию (типа как "запустить игру"), а потом снова отдать эти 3 мегабайта и выйти из приложения. Зачем выделять память под класс который очевидно один на все приложение - и почему нельзя было выделить просто кусок в BSS я не знаю. Точнее знаю - потому что это Си, и он так устроен, но все же.
Ну на таких моментах сильно прям размер ехе-шника не сократишь :) Но, если, конечно вам интересно этим заниматься...
Главная проблема kkrieger'a даже не в том, что он не 64кб, и слегонца так прожорлив, а в том, что в него не интересно играть ) (имхо, конечно).
ЗЫ: кстати есть современный проект 64к-шутера: https://daivuk.itch.io/quod
Вот еще бы чуваку кто-нибудь озвучку и визуальные эффекты помог сделать, а то пресновато как-то :)
Что находится внутри Micropolis