You are not logged in.
Pages: 1
Сап, форум.
Представляю urbi et orbi необычный проект, в некотором роде развитие gta_dll. Если подробнее, то это набор исходников движка SA на С++, восстановленных на основе реверса оригинального .exe, а также PS2/Android/XBOX версий как самой игры, так и предыдущих её частей.
Разумеется, на данный момент исходники покрывают небольшую часть движка. Де-факто, цель проекта - EU/US 1.0. Звучит это весьма амбициозно, и не факт что работоспособный вариант вообще будет иметь место быть, но материал, появляющийся в результате реверса, можно использовать в модификациях уже сейчас - для множества функций подписаны адреса, для полей - оффсеты.
Отмечу, что в мои планы, в общем-то, не входит создание полноценного .exe в одиночку или даже силой 2-3 человек, так как это потребует огромного количества времени. Я лишь разбираю интересные мне части кода. С другой стороны, силами камьюнити сделать более-менее рабочую версию вполне реально - всё зависит от желания и народа. На данный момент над проектом работали я и Seemann.
И да, обращу внимание на то, что проект не является модификацией сам по себе - мы исследуем в первую очередь оригинальные исполняемыe файлы, работающие с немодифицированными ресурсами.
более-менее разобран rw skeleton (базовые исходники приложения, входящие в состав rw sdk).
основная часть 2D (CSprite, CFont, CText и т.д.), более-менее рабочее меню.
частично рабочий стриминг (CStreaming).
из аудио частично разобран стриминг и frontend-SFX.
игра загружает большинство ресурсов (CFileLoader), однако, рендер толком не разобран, поэтому сейчас вместо игры временно рендерится заглушка.
практически не тронуты скрипты, не начат разбор AI и игровой физики.
Проект представляет собой git-репозиторий, доступный для чтения всем.
http://git.nick7.com/x-gtasa.git
Если ты владеешь C++, имеешь базовые навыки работы с git и хочешь поучаствовать, то ознакомься с README, пиши в тему или в личку - выдадим права на запись.
Необходима Visual Studio 2013 (кроме того, удобно, что в ней доступен git, но разумеется, можно использовать и другой клиент). Сборка происходит с toolset'ом v120_xp.
В проект не входит RenderWare SDK 3.7 (вообще, необходим, как минимум, 3.5+) и Direct X SDK, которые необходимы для сборки (подробнее про пути third-party читать в readme.txt). Для сборки с RW D3D8 нужен Direct X 8 SDK; OpenGL билды на данный момент не поддерживаются.
Для запуска приложения необходимы ресурсы от PC-версии (для D3D8/OpenGL-билдов необходима пересборка ресурсов (варианты подключения ресурсов приведены в readme).
Стабильная ветка для сборки – master. Debug/Metrics-билды имеют консоль (~) и вывод дополнительной отладочной информации.
По поводу __DUMMY(), а также именования методов, полей классов и глобальных переменных подробнее расписано в readme.txt.
Следует обратить внимание, что Final (Release)-билды используют /MT вместо /MD.
Last edited by Lego (11-07-2015 03:37)
Offline
Вот минимальный third-party для сборки проекта. Напомню, что в репо он не входит (RW - по понятным причинам, а DirectX SDK лучше скачать с сайта Microsoft со вчеми сопутствующими утилитами).
Offline
Как человек, заваривший эту кашу, могу только порадоваться.
А вот по исполнению - у меня есть вопросы.
Во-первых, как предполагается это отлаживать? gta_sa_dll неспроста был именно .dll - там я шел, последовательно заменяя куски кода и проверяя, как заменилось. Более того, можно было вызвать оригинальную функцию и сравнить результат.
Как это предполагается здесь?
Дальше... имеет ли смысл цепляться за библиотеки от RWG ? Учитывая количество кода, которое из них используется, не проще ли его переписать? (я ведь даже начинал это, и какой-то ощутимый кусок сделал)
И еще... Нужно ли тянуть заведомо устаревшие решения? Например, те же пулы, в пятерке почти такие же, но аллокация в них гарантировано за O(1). Всех изменений - по паре строчек в конструкторе, alloc и release.
Offline
Во-первых, как предполагается это отлаживать? gta_sa_dll неспроста был именно .dll - там я шел, последовательно заменяя куски кода и проверяя, как заменилось. Более того, можно было вызвать оригинальную функцию и сравнить результат. Как это предполагается здесь?
Честно говоря, создавать огромную dll-ку с тысячами хуков, привязанных к одной реализации - сомнительное удовольствие. Хотелось бы замахнуться подальше. Тем более, что сейчас мы имеем гораздо больше информации о движке SA, чем шесть-восемь лет назад.
В крайнем случае, кстати, никто не мешает сделать dll с хуками, подключив к ней необходимые заголовки из проекта и посмотреть как себя ведёт оригинальный исполняемый файл.
Дальше... имеет ли смысл цепляться за библиотеки от RWG ? Учитывая количество кода, которое из них используется, не проще ли его переписать? (я ведь даже начинал это, и какой-то ощутимый кусок сделал)
Это не первоочередная задача, но, думаю, к этому всё и так придёт, если проект будет как-то развиваться.
RenderWare Graphics берёт на себя, на мой взгляд, не сколько рендер, сколько работу с ресурсами: стоит ли сейчас тратить на это время, когда есть ещё куча нерешённых проблем?
И еще... Нужно ли тянуть заведомо устаревшие решения? Например, те же пулы, в пятерке почти такие же, но аллокация в них гарантировано за O(1). Всех изменений - по паре строчек в конструкторе, alloc и release.
Зависит от конкретного случая - в данном случае стоит поправить. Обычно, я делаю такие фиксы опциональными при помощи макроса - и для наглядности, и чтобы была возможность собрать наиболее приближенный к оригиналу вариант (к примеру, см. _USE_WIDESCREEN_FIX).
Last edited by Lego (11-07-2015 03:34)
Offline
Касательно .dll - там получается порядка 100 хуков.
В общем случае - это достаточно сильно помогает - когда стремишься минимизировать количество хуков, с одной стороны, лучше получается разбиегие на модули, с другой - собираются статические объекты (когда нужен один адрес большого объекта, например, CPopulation, а не полсотни ссылок на его поля).
Работы с ресурсами в RWG практически нет, если не считать чтение RwStream. Там по коду получается совсем чуть-чуть, строчек триста, и это именно та часть, которая сильно помогает разобраться в структуре объектов RW. Большая часть у меня была сделана (я не вспомню точно, чего там не было, кажется, было недоделано чтение нескольких чанков).
Offline
Касательно .dll - там получается порядка 100 хуков.
Очень оптимистичный прогноз ^_^. По большому счёту, чтобы получить рабочую dll, нужно заменить достаточно много моих функций с макросом __DUMMY() - а их только при запуске игры вызывается около 300. Плюс перехватить обращения к глобальным объектам.
Кстати, CPopulation имеет только статические поля, поэтому, по-хорошему, на каждое его поле должна быть своя ссылка, иначе, опять-таки, будем привязаны к одному .exe.
Работы с ресурсами в RWG практически нет, если не считать чтение RwStream. Там по коду получается совсем чуть-чуть, строчек триста, и это именно та часть, которая сильно помогает разобраться в структуре объектов RW.
Я сюда включаю работу с RwFrame, RwAtomic, RwImage, RwRaster, RwTexture и т.д. Сам RWGraphics тут, по сути, выступает в роли менеджера объектов этих типов, предоставляя более-менее кроссплатформенный API.
Текущая реализация в ogRW.cpp не настолько гибкая без системы плагинов - на мой взгляд, довольно неплохой фишки. Сейчас там, практически, аналоги Rw-структур, только с методами вместо функций. Неплохое начало, но на более-менее рабочую замену RW нужно ещё N-ое количество времени. Если это действительно интерсено, то можно создать проект в солюшене и постепенно переписать необходимый набор функций, но я бы пока что переключился на более актуальные задачи - по крайней мере, мне всё сразу не потянуть.
Я сейчас занимался аудио (ветка work7), так как эта область относительно нетронута и мне интересна. Попутно ещё смотрю xbox-версию, она довольно похожа на ПК, многие структуры сходятся, хотя и имеются интересные отличия. Например я восстановил забавные штуки типа CMemoryHeap и CMemoryMgr::PushMemId.
И напоследок у меня вопрос - откуда в 2009-м было известно название некоторых невиртуальных классов (например, СAERadioTrackManager)? Ведь RTTI не хранит строки для названий невиртуальных классов.
Last edited by Lego (13-07-2015 23:52)
Offline
И напоследок у меня вопрос - откуда в 2009-м было известно название некоторых невиртуальных классов (например, СAERadioTrackManager)? Ведь RTTI не хранит строки для названий невиртуальных классов.
Ходили слухи, что на ранних этапах разработки MTA (еще в период GTA3/VC) им помогали сами рокстаровцы, во всяком случае частью документации по коду игры. После скандала с Hot Coffee, вроде как перестали. Но это слухи на уровне ОБС.
Offline
Ходили слухи, что на ранних этапах разработки MTA (еще в период GTA3/VC) им помогали сами рокстаровцы, во всяком случае частью документации по коду игры. После скандала с Hot Coffee, вроде как перестали. Но это слухи на уровне ОБС.
Если такое действительно имело место быть - хотелось бы взглянуть надокументацию.
Вероятнее, что просто есть билды с более подробными логами, отладочной инфой или экспортом символов - различных версий исполняемых файлов же довольно много.
Last edited by Lego (15-07-2015 13:49)
Offline
Поздравляю Lego с выходом в паблик! Жаль, не способен ничем помочь в этом сложном и полезном деле.
Немного пооффтоплю, но уж очень хочется спросить listener'а:
осталось ли что-нибудь от похожего openLC?
не моё дело, конечно, но чем продиктовано решение разрабатывать просмотрщик скриптов RDR на JS?
Offline
Касательно .dll - там получается порядка 100 хуков.
Очень оптимистичный прогноз ^_^. По большому счёту, чтобы получить рабочую dll, нужно заменить достаточно много моих функций с макросом __DUMMY() - а их только при запуске игры вызывается около 300. Плюс перехватить обращения к глобальным объектам.
Кстати, CPopulation имеет только статические поля, поэтому, по-хорошему, на каждое его поле должна быть своя ссылка, иначе, опять-таки, будем привязаны к одному .exe.
А здесь начинается группировка. Если к каждой переменной обращаться отдельно, то хуков будет немерянно.
Но, в исходном коде, переменные и функции обявляются внутри модуля, и обращений извне достаточно мало.
Т.о., если мы реализуем всю (или, хотя бы, большую часть) функциональности модуля, переменные, не используемые извне можно будет оставить внутри своего модуля и не обращаться к ним в игровой памяти.
CPopulation - статический экземпляр объекта. Все обращения непосредственно к полям сгенерированы оптимизатором.
Для IV я объявлял и CPopulation и CPopCycle (вот он - просто огромный, 17М)
Работы с ресурсами в RWG практически нет, если не считать чтение RwStream. Там по коду получается совсем чуть-чуть, строчек триста, и это именно та часть, которая сильно помогает разобраться в структуре объектов RW.
Я сюда включаю работу с RwFrame, RwAtomic, RwImage, RwRaster, RwTexture и т.д. Сам RWGraphics тут, по сути, выступает в роли менеджера объектов этих типов, предоставляя более-менее кроссплатформенный API.
Текущая реализация в ogRW.cpp не настолько гибкая без системы плагинов - на мой взгляд, довольно неплохой фишки. Сейчас там, практически, аналоги Rw-структур, только с методами вместо функций. Неплохое начало, но на более-менее рабочую замену RW нужно ещё N-ое количество времени. Если это действительно интерсено, то можно создать проект в солюшене и постепенно переписать необходимый набор функций, но я бы пока что переключился на более актуальные задачи - по крайней мере, мне всё сразу не потянуть.
А здесь, все зависит от того, что мы хотим.
У меня была конкретная цель: сделать нечто, что может полностью заменить ту часть RWG, которая используется в SA.
Развивать серьезно, в том виде, в котором оно есть - непродуктивно. Для начала - хотелось перейти полностью на собственный код не сильно отступая от идеологии, а потом уже думать, что можно улучшить.
Заниматься этим прямо сейчас некогда, да и я уже давно переключился на RDR и пятерку.
Немного пооффтоплю, но уж очень хочется спросить listener'а:
осталось ли что-нибудь от похожего openLC?
не моё дело, конечно, но чем продиктовано решение разрабатывать просмотрщик скриптов RDR на JS?
openRage/IV - осталось порядка мегабайта кода.
openRage/MP3 - еще полмегабайта (в основном, графика)
Еще есть немного по RDR и пятерке, но там, в основном, всякая инструментальщина - дамперы карт и т.д.
Сейчас я пытаюсь как-то навести в этом порядок, а то пять разных версий только для реализации atPtr/atArray/atMap - немного напрягают.
Учитывая, что я мотаюсь по планете, как укуренный страус (40 000км - кругосветка - толко за последние три месяца) - времени на это найти проблематично
А JS я просто люблю, и, сейчас пишу практиески только на нем (я просто не вижу никакой альтернативы)
Offline
CPopulation - статический экземпляр объекта.
Не знаю как там с GTA4/5, но в GTA3 - нет:
http://git.nick7.com/x-gtasa.git/blob/H … txt#l18263
Можно, конечно, объединить поля в единую структуру, но я, по возможности, придерживаюсь определений Rockstar.
Для начала - хотелось перейти полностью на собственный код не сильно отступая от идеологии, а потом уже думать, что можно улучшить.
Сейчас это вообще ко всему репозиторию относится.
Единственное, где я отошёл от оригинального EXE - вынес большинство обращений к WinAPI в OSWrapper, как было сделано на мобильных платформах.
По сабжу:
- добавил возможность сборки с OpenGL (необходимо конвертить ресурсы).
- и со старыми SDK - RW 3.4, RW 3.3 (поддержка сборки с последним, скорее всего, позднее будет убрана).
- более-менее стало работать радио, правда, разобрано оно ещё не до конца.
Кстати, забавно, что UserTrack Player не воспроизводит монофонические файлы в принципе (Хотя, OGG воспроизводит как стерео - пофиксил на скорую руку).
А поддержка WAV сделана только для одного единственного варианта заголовка RIFF - опять же, добавил небольшой фикс.
Реализация MP3 и ещё пары форматов реализована через библиотеку QickTime, но, что-то не особо хочется заниматься подобными извращениями. Думаю, лучше перекатиться на какую-то опенсорсную либу.
Offline
Интересно, что у RWGraphics есть evaluation-версия. В частности, RW3.7 которая лежит на public.sannybuilder.com. Единственная "полная" версия имеющаяся в паблике - RW 3.4 D3D8.
Основное отличие - отрисовка логотипа "RW" слева снизу без возможности его отключить стандартными средствами (аналог RpLogo).
Не знаю, насколько это легально, но я отключил рендер просто сделав хук функции _rwCameraValRender.
extern "C" void _rwCameraValRender(RwCamera * camera);
Offline
Pages: 1