Динамически подключаемые библиотеки (dynamic link libraries, DLL) используются для уменьшения объема исполняемого файла, за счет выделения некоторых функций в отдельный файл. Более того, функции из DLL могут использовать разные загрузочные модули, что особенно важно для жизнедеятельности Windows (например в KERNEL32.DLL содержаться функции управления памятью процессами и потоками). Для создания DLL в среде C++ Builder необходимо выбрать File\New\Dll при этом автоматически генерируется проект, компиляция которого и дает искомый результат. Для написания экспортируемых функций используется следующий синтаксис: __declspec(dllexport) void nameFunc(); При компиляции, кроме прочих, создаются файлы с расширениями *.LIB и *.DLL, содержащие экспортируемые функции. Подключение DLL в C++ Builder возможно явным и неявным способом. При неявной компоновке в секцию директив необходимо добавить строку вида: #pragma link ”nameFile.lib” а, в секцию прототипов добавить описание прототипа функции: void nameFunc(); При неявной компоновке функция вызывается по имени, необходимы файлы с расширениями *.LIB и *.DLL. Библиотека подключается к процессу в момент загрузки процесса и выгружается вместе с процессом. Явная компоновка требует использования функций WINAPI LoadLibrary() и GetProcAddress(). В данном случае функция вызывается по номеру, который ей присвоен при создании DLL. C++ Builder упорядочивает экспортируемые функции DLL в алфавитном порядке их имен. Номер функции в DLL можно получить с помощью утилиты tdump с ключом -ee. Функция LoadLibrary() принимает в качестве параметра имя библиотеки, а возвращает переменную типа HINSTANCE. Функция GetProcAddress() имеет следующий прототип: void *GetProcAddress (HINSTANCE, const char *); она принимает переменную типа HINSTANCE и символическую константу, а возвращает указатель на функцию. В приведенных листингах демонстрируется создание, неявная и явная компоновки DLL. //Пример создания DLL #include <vcl.h> #pragma hdrstop int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) { return 1; } //Выше находится заголовок DLL, генерируется автоматически double dblValue(double); double halfValue(double); __declspec(dllexport) int AreturnValue(bool); __declspec(dllexport) int CreturnValue(bool); __declspec(dllexport) int BreturnValue(bool); int CreturnValue(bool i) { i= true; return(2); } int BreturnValue(bool i) { i= true; return(3); } int AreturnValue(bool i) { i= true; return(1); } double dblValue(double value) { return value * value; }; double halfValue(double value) { return value / 2.0; }
//Пример неявной компоновки DLL #ifndef useDllU1H #define useDllU1H #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //-------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TLabel *Label1; TLabel *Label2; TLabel *Label3; TButton *Button1; void __fastcall Button1Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //-------------------------------------------------------- extern PACKAGE TForm1 *Form1; //-------------------------------------------------------- int AreturnValue(bool); int CreturnValue(bool); int BreturnValue(bool); #endif
int (*returnVa1)(bool); int (*returnVa2)(bool); int (*returnVa3)(bool); //-------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) {//Создание формы hinst=LoadLibrary("dll_cb_c.dll"); returnVa1=(int (*)(bool))GetProcAddress(hinst, MAKEINTRESOURCE(1)); returnVa2=(int (*)(bool))GetProcAddress(hinst, MAKEINTRESOURCE(2)); returnVa3=(int (*)(bool))GetProcAddress(hinst, MAKEINTRESOURCE(3)); } //На форме имеется одна кнопка и три метки void __fastcall TForm1::Button1Click(TObject *Sender) { bool buf_b; int j; buf_b=false; if(returnVa1==NULL) Label1->Caption=AnsiString("Error"); else { j=returnVa1(buf_b); Label1->Caption=AnsiString(j); } Label2->Caption=AnsiString(returnVa2(buf_b)); Label3->Caption=AnsiString(returnVa3(buf_b)); } MAKEINTRESOURCE — макрос для создания символической константы. Переменная типа HINSTANCE создается глобально. Загрузка библиотеки и присвоение указателей на функции производится в момент создания формы. Количество и тип параметров в описании функций (сигнатура функции) в DLL и указателя на функцию, в вызывающем модуле должны совпадать, совпадение имен не обязательно. DLL выгружается из памяти при завершении работы вызывающего модуля. Принудительная выгрузка DLL осуществляется функцией FreeLibrary(HINSTANCE).
Чтобы убрать "тормоза в игре" или одним словом улучшить производительность необходимо открыть в ХЕКС-редакторе (см. ссылку сверху) XR_3DA.exe, там в коде с помощью поиска найти цифры 45 78, найти их просто - ввести в поиске GlobalMemoryStatusEx . Далее изменить их на 00 00 и сохранить изменения. Всё. Теперь всё будет работать нормально. Способ нашёл не я - Rolan.
(С) _Призрак_ Инструкция по изменению плотности травы. Параметр меньше 0.02 не ставить - Колмогор писал что начинает лагать 1. Открываем айда 2. Открываем айда_виев 3. Теперь ищем что нам нужно найти. Нам сейчас нужно найти r__detail_density? Тогда жмем ctrl+t и вводим r__detail_density 4. Находим функцию и тщательно ее разбираем (я ее полностью разбирать не буду, а только укажу где задаются параметры: fld ds:flt_10064400 --нижнее ограничение равное 0.6 or dword_1007CACC, 8 sub esp, 8 fstp [esp+30h+var_2C] mov ecx, offset unk_1007CA9C fld ds:flt_10064380 --верхнее ограничение равное 0.2 fstp [esp+30h+var_30] push offset aSs; "ЪЩЩ>" push offset aR__detail_dens; "r__detail_density" call ds:??0CCC_Float@@QAE@PBDPAMMM@Z; CCC_Float::CCC_Float(char const *,float *,float,float) push offset sub_1005E080; void (__cdecl *)() call _atexit add esp, 4 Если вы заметили, то что бы трава стала плотней нужно уменьшить параметр, а что-бы травы стало меньше нужно параметр увеличить 5. Нам нужно увеличить плотность травы: следовательно нужно изменить верхнее ограничение. Как это сделать? Есть 3 варианта:
Первый и самый логичный вариант: изменить переменную которая задает. Но тут есть небольшой подвох на котором я попался. Этой переменной может пользоваться не одна функция, а несколько. И не ясно что вы можете сломать, поменяв одну циферку в переменной...
Второй: взять другую уже существующую переменную. Хороший вариант которым я и воспользовался. Но и тут есть недочет - переменных в ддлке не так уж и много и можно просто не найти нужную
Третий: создать переменную. Отличный вариант. Единственный минус - я не знаю как это сделать
Я пошел по второму пути. Два раза шелкнув на ds:flt_10064380 айда отправила меня в дебри под названием .rdata. Там я нашел переменную которая называлась - flt_1006452C и которая имела значение 0.0720999 Вообще-то, как я понял, flt_1006452C - не является названием переменной. Это так сказать сборка из 2 показателей - (тип числа)_(оффсет) В нашем случае это число типа float которое находится в 1006452C. Ну чтож приступим к редактированию! 6. Отправляем в самое начало файла. Как? Сверху есть что-то типа статус бара - строка состоящая из синего,серого,черного цвета. Нажимаем там в любом месте мышкой и ведем влево до конца 7. Опять ищем r__detail_density. Находим в этой функции fld ds:flt_10064338. Дальше самое интересное. Жмем на ХЕКС_ВИЕВ и там у нас выделяются какие-то цифры. Это наше 10064338 только написано наоборот. Сравните: 38 43 06 10 10 06 43 38 Похоже, не правда? Начинаем редактировать. нам нужно поменять 4338 на 452C т.к. в этом и есть различие. Жмем правой кнопкой мыши на этих цифрах и выбираем пункт Edit. Меняем 38 43 на 2С 45. Дальше жмем где нибудь в коде. Это нужно сделать обязательно. После этого жмем правой кнопкой мыши и выбираем commit changes. Но айда не меняет исходный файл. В нашем случае мы можем только создать файл изменений. Делается это так - Файл - Produce file - Create DIF file. Назовем его test. DIF файл можно открыть при помощи блокнота и посмотреть что вы сделали. Теперь так сказать соединит этот файл и дллку. Это можно сделать при помощи bpatch. Качаем и смотрим и запускаем bpatch.cmd. Я думаю что вы сможете его изменить сами если нужно будет. Там все элементарно.
Сообщение отредактировал RETRIX - Воскресенье, 04.03.2012, 23:11
Amicron, получении информации из интернета это круто, а возможно ли сделать открытие страниц интернета в игре?
Думаю можно, но это будет не в тему. Как можете связать интернеты с игрой? RETRIX, меня не было какой-то промежуток времени, есть какие-нибудь изменения? Что интересного покажете?
PorShen, Вроде да, хотя я не пробывал, почитай вот эту тему, может что и найдёшь - http://ap-pro.ru/forum/21-509-1. Там вроде-бы задовали такой вопрос, но я просто сам тебе ответить не могу, так как я в этом деле не очень...
Добавлено (02.01.2012, 13:04) --------------------------------------------- Ой, блин, извени, ошибся. Не было там такого вопроса. Там всего 3 поста. Короче это в теме на амк задавали про дальность прорисовки травы, я ща почитаю, постараюсь найти ответ.
PorShen, на амк про плотность травы говорили, а вам дальность нужна, это в настройках есть. Да и вообще, что бы подгрузить всю траву на уровне, вам не просто супер компьютер нужно, а сервер как минимум. Уровни в сталкере большие и нодов с травой много, делайте выводы.
Вот...вспомнил... 1.Можно вернуть табличку с переходом как в ТЧ,но как?Без копания движка-не обойтись.Также,в эту тему.Как сделать отметки переходов,в Sigerous и АМК восстановиили. 2.Насчёт bass liblary,возможен ли выход в интернет?Что если выстроить в ПДА Браузер,мини-чат,сделать сервер миничата,и прямо с игры переписываться с другими игроками..Как думаете? 3.Хм,разрушение в игру можно внести,хотя бы мелких объектов:падение ламп,при взрыве гранат? (Надо в SDK полазить)
PorShen, таблички с переходами сделаны скриптами. Библиотеки BASS - это звуковой движок, выход в интернет с него доступен, но только в виде проигрывания потока. Встроить браузер, думаю можно, но очень много мороки будет с самим интерфейсом, программно можно написать, а вот как сделать интерфейс, ведь сталкерский lua очень урезан. Хотя не думаю, что такая идея будет популярна среди игроков.
Так стоп...я думал, что соединение с инетом в одиночке сталкера реально возможно только чтением медиа и текста, а тут оказывается можно и браузер создать! Так довайте, когда Amicron, вы доделаете плеер, сделаем простейший браузер? Чисто чат. Это же отличная идея.
А теперь представьте, сидит в этом чате человек 1000 и сообщения выводятся на экран, и угол левый у вас заполнен всё время. Браузер дело хорошее, но никто сервера держать не будет, у меня интернет не всегда присутствует, да и других дел море. Да и вообще, такими способами, через host, делать не хорошо, это по сути эксплоит. Вообще там внедрение в адресное пространство идёт левого кода, а если сама игра своей функцией обратиться к какому-нибудь адресу, а там у вас к примеру чат или тот же плеер, то будет вылет. В итоге мы имеем фишку со случайными вылетами. Они будут, я вас уверяю, чем больше детище, тем больше оно кушает памяти. RETRIX, сделать можно всё.
Зачем,у меня есть свой сайт.На нём есть мини-чат,который не требует сервера. Можно заменять любой модуль на мини-чат. Вот сайт,кстати. Да простит меня администрация. Можно вклеить не сам браузер,а html страницу...Хотя лучше,простейший браузер,открывающий одну страницу.
Добавлено (03.01.2012, 12:35) --------------------------------------------- А насчёт экрана.Нам необходимо будет открывать ПДА,чтобы читать записи.Это раз,а во вторых,можно сделать информер,что при новом сообщение в чате,рядом со стаминой и жизнями сделать маленькое изображение пда,которое будет мигать при новом сообщении.Эх,скорее бы нашу модификацию доделать,да ввести эту штуку.Будет намного веселее. Хм,а вариант ли ввести кооператив...Хотя много мороки.
Сообщение отредактировал PorShen - Вторник, 03.01.2012, 12:28
Amicron, понятно. Выходит от мини-чата придётся отказаться?
PorShen, тогда иконка ПДА рядом со стаминой будет мигать всегда =) А так идея неплохая, если ты знаешь, о чём говоришь, и как избежать конфлигтов игры с кодом браузера, который вроде-бы динамический и гибкий, да?
Если на то пошло, то джаббер движок интегрировать, на словах всё легко. Вроде что там интерфейс, в хмл там только координаты, а в скриптах действия и всё остальное. Вы основы выучите, а потом и за серьёзное беритесь. Кто основу писать будет? Что-то я тут не вижу программистов-энтузиастов. А кооператив в соседней теме клепается, вам туда.