Но написать надо! Ведь использование готового – не есть путь для настоящих джедаев (дада, напишу потом компилер, ОС, комп спаяю, генератор энергии сооружу и т.п.)
Итак, что изменилось:
1. Ололош, внутри опять всё переписал, на этот раз намного чётче! GUI теперь может хендлить разные виды топологии геометрии (юзаю для линий)
2. GUI теперь поддерживает рендеринг сплайнов! Юхуу!
3. ДОБАВИЛ НАКОНЕЦ Drag & Drop !! Вон на скрине у нодов есть синие хреньки – прямоугольники! Просто наживаем мышей на один и перетягиваем на другой, отпускаем мышь иии..БАЦ ) Сплайном соединились! Чотко же! = )
Осталось сделать удаление связей (и дохрена контролов типа TabControl ). WTF! Уже 4:25!!!!!!! Ушёл спать, срочно!
Вот оно, ребята, GUI моей мечты! 😀 Не, ну оформление конечно кака, но не суть ) Главное ведь что оно своё :3
upd: дада! Опять без скина GUI ) Скины поддерживаются но мне лениво их рисовать 😀
Что изменилось:
Теперь рендеринг всего GUI идёт обычно в 1-5 DIP-ов а не в 100500 как раньше. Сам по себе GUI не только может, но и рисуется ровно в 1 DIP, однако дополнительные ДИП-ы нужны, если в нём юзаются пользовательские текстуры! На скрине, приведённом выше, количество DIP-ов = 3 потому что вон та хренька красная сверху слева – это текстура сцены, которая какраз перед рендером GUI и рисуется. Из за неё и не 1 а 3 дипа: рисуем GUI до картинки, рисуем картинку, рисуем остальное.
То есть я вместо моего адски дебилоидного рендеринга (каждый элемент рисовал сам себя, имел СВОЙ вершинный и константный буфер..омг) сделал чоткий батчинг : )
На самом деле это конечно не сложно совсем. Но кое что изначально слегка напрягло: родительские контролы должны собой обрезать дочерние контролы, чтобы дочерние не рендерились за границами родительских. Раньше я рекурсивно рендерил, постоянно спуская ScissorRectangle и применяя его для каждого контрола. И было всё вздрыжне. НО! Теперь то у меня всё всё всё может нарисоваться за 1 DIP! И Scissor хардварный не применить ( Бида! Вот пришлось симулировать его – вручную обрезаю scissor-ом квады контролов (модифицирую геометрию и текстурные координаты квадов). Впринципе тоже детсвкая задача : ) Обрезание геометрии делается прямо во время её генерации, а генерация вызывается если изменился scissor. Всё просто.
На скрине новые контролы (сейчас сел и допилил их):
1. ScrollBar – он один для вертикального и горизонтального скроллирования! Конструктор требует, чтобы юзер указал направление скроллинга
2. ScrollablePlane – вон тот квадратик посреди скрина с 2 скроллами сразу. ScrollablePlane – наследник Plane + добавил скроллы. Можно скроллить теперь контент очень удобно : ) Надо бы прикрутить “кинетические скроллы” (точнее эти модифицировать), чтобы можо было дёрнуть ползунок, а он ещё будет некоторое время двигаться, останавливаясь (как сейчас на мобилах любят делать)
Adios, ушёл дальше болеть : (
Первое, что пришло в голову – подменить у класса виртуальный метод :3 Легального способа тут конечно нет, но just for fun можно VisualStudio-only намутить код ) Всё тут просто – у каждого объекта любого класса при наличии в классе виртуальных методов в самом начале записывается указатель на таблицу виртуальных методов этого класса. Таблица – просто набор указателей на методы! Осталось написать подложный метод и перезаписать указатель в таблице виртуальных методов ^^ Что я, собственно, и сделал. И.. и обломался: access violation writing location… )
vtable записывается в read-only память : Бида… казалось бы ) Но за что я люблю С++ (в отличае от шарпа на котором раньше писал) – в нём можно сделать всё, даже то, что запрещено 😀
VirtualQuery, VirtualProtect спасут отца Русской демократии.
struct Foo
{
virtual void VirtualMethod(){
printf(“VIRTUAL METHODn”);
}
};
void ReplacementFunc(){
printf(“LOL FUNCTION!!n”);
}
int _tmain(int argc, _TCHAR* argv[])
{
typedef void (*func)();
Foo* foo = new Foo();
size_t* vtbl;
memcpy(&vtbl, foo, sizeof(size_t));
func ptr = &ReplacementFunc;
MEMORY_BASIC_INFORMATION meminfo;
DWORD oldprotect;
VirtualQuery(&vtbl[0], &meminfo, sizeof(meminfo));
VirtualProtect(meminfo.BaseAddress, 4, PAGE_EXECUTE_READWRITE, &oldprotect);
memcpy(&vtbl[0], &ptr, sizeof(func));
foo->VirtualMethod(); //тадааам ) В консоли: LOL FUNCTION!!
getchar();
return 0;
}
Блджад, почему тут нету тега ? Или есть..
Буду искать новые извращения и потом добавлять сюда, а пока надо делами заниматься.
Продолжил пилить, фиксить баги и т.п. Ноды вроде работают без проблем! Но ноды эти надо связывать между собой! Т.е. выходы одних с входами других.
Для этого везде юзаются кривые Безье. Вот я и подумал – а чем я хуже? : ) Решил погуглить тему, так как раньше не нужна была – не занимался. Погуглил, покурил.. ох ёпт!! Я то думал там будет ацкая жесть с километровыми формулами, а там оказалась детская задачка ))
Вот на своём софтрендере замтил отрисовку этих самых кривых ^^ С-К-А-Ч-А-Т-Ь 90кб всего, статично слинковал с рантаймом (просить не должно). M$ Windows only.
Но главное что дописал – “обрезание” контролов scissor-ом родителя. Я думал, что я сделал это давно, а оказалось не сделал ) 😀 Теперь всё зачОтненько рендерится, быстро и правильно )
Слегка пофиксил сплит-контейнеры, допилил класс виджета-узла графа шейдерного редактора, сделал его ресайзинг )
Скины поддерживаются, однако я их пока не рисовал и контролы просто заливаются дефолтным цветом, который я рендомно выставил как-то однажды и забил : )
Вот WIP (work in progress) скрин того, с чем я работаю. Поясню:
1. Тут не все поддерживаемые контролы 😀 Тут только то, что я прямо сейчас тестирую, не более.
2. Тут нету скина (не применён) и т.е. нет текстур.
3. На скрине 2 сплит-контейнера, 2 кнопки, 1 pictureBox (в который выводится отрендеренная сцена), 1 shaderNode
Мой GUI – сразу же с первых минут жутко зафейлился по всем фронтам ( И началось его дописывание/переписывание. : )
1. Добавил SplitContainer контрол. Нужен мне для UI редактора (ну, это контрол где есть 2 панельки и полоса-разделитель. которую таскать можно). Работает теперь отлично!
2. Сегодня при поддержке одного друга пофиксил 100500 багов в моём текстовом классе! А именно: горизонтальное, вертикальное выравнивание, отступы букв друг от друга, правильное получение размеров строки (в пикселях) и много чего ещё попутно ). Теперь текст рендерится правильно и чётко по центру (если стоИт выравнивание по центру). В общем _теперь_ я доволен рендерингом текста )
3. Меняю иерархию классов “виджетов”. Теперь моего брутального и бессердечного кода нет. Всё чисто, лаконично и красиво )
Допиливаю другие контролы… скоро будут скрины ^^
Добавил поддержку over 20 опкодов процессора, начал писать PPU (сделал запись контрольных регистров 1,2 и чтение регистра состояния). Нашёл баг в JSR опкоде – пофиксил ) Более подробно в моём блоге на gamedev.ru http://www.gamedev.ru/pages/l/forum/?id=152486 (это страница с комментами – я в комментах больше всего постю – не хочу засирать раздел своими постами )
Вчерашней ночью решил же писать эмулятор денди! О ДААА! 😀
Создал пустой проект, написал создание окошка, копирование ROM-а в память. Cool!! What next?? o_O Эм… ээм.. вырубил всё нафиг и пошёл спать ; ) “Верное решение”(с)
Сегодня решил таки вернуться к вопросу, ведь “врагу на сдаётся наш гордый Варяг”! начал с гугления архитектуры Famicom. Этой системе уже куча лет, она жутко старая, но в инете так и нет нормальной полной скомпонованной инфы о ней 😀 Блджад! Приходится гуглить по кусочкам.
Окей, базовая инфа есть, почитал про CPU, PPU, APU, memory mapped IO и т.п. Ну это всё конечно весьма увлекательно, только представления о том, как это всё реально работает и как собсно это эмулировать досихпор нет! : Что-то типа “смотрим в книгу – видим фигу” Но.. останавливаться же не в моих правилах )
Пошёл потроллил в Skype чатике товарищей Utechenko V. O. и DDS, которые таки выдали чуток полезной мне инфы, в частности направили “на путь истинный” – посоветовали книги Владислава Пирогова, которые оказались весьма занимательными : )
Так я пришёл к мысли, что “блин, ведь давно пора выучить ассемблер” ! Используя книги, туториалы по программированию AVR микроконтроллеров, туториалы по ассемблеру, википедию, параллельно распивая зелёный чай, поедая сгущёнку и печатая очередной рендер из VRay матеря принтер за баги в печати начал постигать азы микроэлектроники, ассемблерного программирования.
Чёрт! Это чувство просто офигенно! Чувство, когда начинаешь понимать нечто ранее недосягаемое.. как звёзды ) Ещё вчера сидел тупил, не понимал _совершенно ничего_ в архитектуре и уже сегодня я знаю назначение северного, южного мостов, чипа CMOS, что такое защищённый режим процессора и как в него переходить ) Назначение APIC (контроллера прерываний) да и саму суть прерываний! Я раньше вообще не представлял что же это такое и нафига оно нужно! Я вообще думал что это какаято хардварная фича проца, которая вызывается через строго отведённый интервал и что-то шлёт в этот момент девайсам. Оказалось всё немного по-другому. APIC контроллер физически приаттачен к выводам девайсов на материнской плате. Девайсы могут слать сигналы прерываний, контроллер ставит соответствующий флаг, который ожидает обработки процессором. Если в процессоре глобально и локально прерывания не запрещены, то обрабатываются они по очереди следуя приоритету. Для каждого прерывания есть свой собственный обработчик! Т.е. – процессор проверяет, стоит ли флаг прерывания и если его можно выполнить – сохраняет состояние регистров (заливает значения в стек), переходит к обработчику прерывания и обрабатывает его, восстанавливает состояние регистров и продолжает выполнение программы.
Не понятен только один момент – ведь во время обработки прерывания могут ещё несколько раз придти сигналы о необходимости выполнить одно и тоже прерывание! Ну тоесть девайс запросит его несколько раз. Что тогда? Насколько я понял – все прерывания кроме последнего тупо пропускаются. Странно это всё. Понятно, что такое может произойти с минимальной вероятностью, но может же : )
Сделал загрузку ROM-а игры NES (выбрал SuperMarioBros как тестовую игру,ибо в нём самая простая архитектура картриджа – нету MemoryMapper-а и т.п.), набросал пока Dummy классы железа NES, обработчики нескольких опкодов процессора, разобрался с обработкой прерываний, обработал Reset.
Ок, хватит тут графоманствовать – ушёл обратно в мир ассемблера..