Cheb's Game Engine

Планы, идеология, архитектура и т.п.

Модератор: Модераторы

Re: Cheb's Game Engine

Сообщение DYUMON » 04.03.2020 05:32:55

Cheb писал(а):Виндовс - это обязательный компонент нормального пека, и стоит соответственно.

Я про то что зачем покупали .
Аватара пользователя
DYUMON
постоялец
 
Сообщения: 204
Зарегистрирован: 11.03.2009 13:32:54

Re: Cheb's Game Engine

Сообщение Cheb » 04.03.2020 13:36:35

Затем же, зачем я процессор и память покупал. Чтобы комп собрать.
Я уже подробно объяснил, почему Линукс мне не подходит.

Просьба болше не флудить в моей теме.

Добавлено спустя 11 часов 40 минут 21 секунду:
Вот это вот состояние "вот-вот, почти" после двух лет непригодности к дальнейшему движению - вы ж не представляете, как выбешивает.
Скачал мегавад sunlust, срываю зло на ни в чём не повинных чертях.

Добавлено спустя 8 часов 33 минуты:
Починил самоперезапуск.
ЧСХ, поведение мьютексов в семёрке изменилось со времён WinXP SP1, под которой я это создавал и отлаживал.
Во первых, в качестве первого параметра надо передавать не MUTEX_MODIFY_STATE, а MUTEX_MODIFY_STATE or SYNCHRONIZE - иначе WaitForSingleObject будет стабильно возвращать WAIT_FAILED и будет невозможно отличить заброшенный мьютекс.
Во вторых, проверять надо на <> WAIT_TIMEOUT, такой результат получается только пока процесс-создатель ещё держит мьютекс.

Код: Выделить всё
{$else unix}
  var
    M: THandle = 0;

  function ThisIsAnOnlyInstance: boolean;
  var
    N: Utf8String;
    d: dword;
  begin
    if M <> 0 then Result:= Yes
    else begin
      N:= Utf8Encode(ChangeFileExt(ExtractFileName(ParamStr(0)),'')
                                                      + 'SingleInstanceMutex');
      if Mother^.State.IsServer
        then N+= Utf8Encode('_srv_' + Mother^.State.ServerModuleName);
       
      M:= OpenMutexA(MUTEX_MODIFY_STATE or SYNCHRONIZE, False, PAnsiChar(N));
      if M = 0 then begin
        M:= CreateMutexA(nil, True, PAnsiChar(N));
        Result:= Yes;
      end 
      else begin
        d:= WaitForSingleObject(M, 0);
        Result:= d <> WAIT_TIMEOUT;
        if not Result then M:= 0; // allow another attempt
      end;
    end;
  end;
{$endif unix}


[тяжкий вздох]
Теперь надо опять проверять в икспи, десятке, вайне под убунтой, вайне под древнеубунтой... :x
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 06.03.2020 21:10:33

Я почти, почти уже доделал - когда зацепился за механизм локализации и соответствующий API. Понадобилось.. нгх... добавить.. всего... одну.. гх.. ААА, я не могу! Это сраное говно мозолило мне глаза годами, раздражая, бросая вызов своей убивищной корявостью! Всё! В ады! В переделку! :twisted:

..и увяз в очередном рефакторинге, изобретая новый формат l10n с определением и автоподстановкой падежей и числительных форм. :cry:
{$LANGUAGE RU()|GRCA_NOMINATIVE,,кто_что\GRCA_GENITIVE,,кого_чего\GRCA_DATIVE,,кому_чему\GRCA_ACCUSATIVE,GRCA_GENITIVE,кого_что\GRCA_INSTRUMENTAL,,кем_чем\8,,о_ком_о_чём}
{$LANGUAGE EN()|}
{$LANGUAGE DE(EN)|GRCA_NOMINATIVE,,Nominativ\GRCA_GENITIVE,,Genitiv\GRCA_DATIVE,,Dativ\GRCA_ACCUSATIVE,,Akkusativ}
{$LANGUAGE ES(EN)|GRCA_NOMINATIVE,,Nominativo\GRCA_ACCUSATIVE,,Acusativo\GRCA_DATIVE,,Dativo\GRCA_GENITIVE,,Genitivo\8,,Disyuntivo}

Изображение
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Alex2013 » 09.03.2020 18:13:52

Cheb писал(а):
Ну и "экран" размером "со стену дома" конкретно под "нативную" Sony PS 2 тоже "то еще зрелище из старых блокбастеров"


Абсолютный эпик

Угу ! Как то так ...
ИзображениеИзображение
Или даже так ... :D
ИзображениеИзображение
(Типа: что будет делать миллионер впав в детство?
Построит кинозал и будет играть на его экране в старые игры !)

Добавлено спустя 22 минуты 35 секунд:
Cheb писал(а):Я почти, почти уже доделал - когда зацепился за механизм локализации и соответствующий API. Понадобилось.. нгх... добавить.. всего... одну.. гх.. ААА, я не могу! Это сраное говно мозолило мне глаза годами, раздражая, бросая вызов своей убивищной корявостью! Всё! В ады! В переделку!


А я так надеялся что скоро запущу долгожданную демку ! :cry: А тут такой облом ...
Alex2013
долгожитель
 
Сообщения: 1819
Зарегистрирован: 03.04.2013 11:59:44

Re: Cheb's Game Engine

Сообщение Cheb » 10.03.2020 11:40:07

(Типа: что будет делать миллионер впав в детство?)

Эпичненько :D Примерно так я это и представлял... Но не с таким размахом.

А тут такой облом ...

Ну, я того же мнения.
Но есть говна, которые надо разгресть.
Две трети работы уже сделано, ресурсные строки переведены в новый формат локализации, парсер готов и окучивает, внутренний формат во всём движке переведён на юниксовые абзацы (#10), виндовые #13#10 подставляются непосредственно перед записью в журнал или WriteLn в консоль, все строки в движке переведены с #13#10 на '%n', функция CgeFormat() научена новым трюкам с числительными типа 'ЦП %0%n x%1 %(%ч(логическое ядро\логических ядра\логических ядер)|%1)%n кэш второго уровня: %2, линейка %3'... Осталось изменить порядок хранения названий в *.module файлах да переделать менеджер ресурсных строк игрового модуля, чтобы часть зоопарка держал сам, а часть сосал у матки - но с умным кешированием и преобразованием enum'а через строку, на случай, если константы у модуля и матки не совпадают.

..и выходные кончились. Ааа, какой большой и толстый!
..конь, который на работе не валялся.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 14.03.2020 02:24:46

Гребу, гребу, гребу-гребу-гребуГРЕБУГРЕБУГРЕБУ :evil:

Выполол ужосныя баги с арифметикой указателей. Похерил эстетские константы Yes и No (из девяностых тащил, из своего первого движка!), заменив штатными True и False. Прошёлся метлой, исправляя те немногие места, где использовались WriteLn, MessageBoxW и иже с ними. Попутно раскомментировал, упорядочил и пофиксил код, обеспечивающий поддержку совместимости с Windows 98 - на случай, если впаду в маразм и решу её вернуть. В частности, много кода служит детектированию версии Win98 без установленного патча Internet Explorer 5, где W* функции - неработающие заглушки. Подобная ситуация надёжно распознаётся и большинство алгоритмов переключаются на резервные не-юникодные варианты, предполагая системную кодировку cp1251. Не забыть, кстати, добавить подобную поддержку в мои классы работы с файлами, они-то все на W* функциях построены.
Много кода служит динамической загрузке функций WinAPI, которые добавились только в 2000-й или XP и поэтому все использующие их алгоритмы должны иметь версии, где они not Assigned.

Добавлено спустя 16 часов 39 минут 5 секунд:
Разгрёб до компилируемости, доделал механизм, упал без сил.

Добавлено спустя 16 часов 22 минуты 19 секунд:
Собрал под 64 бита. Сначала упёрлось в нехватающий "доделаю когда-нибудь потом" кусок, пришлось прикручивать дополнительные городушки и давать каждому чанку диспетчера памяти отдельный постоянный (не скользящий) индекс.

Потребовалось вот для этих поросяток, нужных для будущего многослойного мира (ссылки на инстансы соседних слоёв хранятся в ускоренных полях). Для 32 бит тупо каст указателя к dword'у. А вот под 64 бита... Смотрите сами:
Код: Выделить всё
  {$ifdef cpu64}
    function UnpackDwordToChepersyObjectReference (
                                            d: dword): TChepersyObject; inline;
    var chunk: TChepersyMemoryManagerChunk;
    begin
      if d = 0 then Result:= nil
      else begin
        chunk:= TChepersyMemoryManagerChunk(
                                        CpsMemoryManager.CIdx2Chunk[d shr 16]);
        Assert(Assigned(chunk)
         , 'Failed to unpack a dword to an object reference: no such memory manager chunk!');
        Result:= TChepersyObject(pointer(qword(
          qword(pointer(chunk)) + qword(d and $0000ffff) shl CpsMMAllocGranPoT
        )))
      end;
    end;
    function PackChepersyObjectReferenceToDword (
                                            o: TChepersyObject): dword; inline;
    var chunk: TChepersyMemoryManagerChunk;
    begin
      if not Assigned(o) then Result:= 0
      else begin
        chunk:= o.GetMemoryManagerChunk;
        Result:= (dword(chunk.CIdx) shl 16)
           or (dword(qword(pointer(o)) - qword(pointer(chunk)))
                                                       shr CpsMMAllocGranPoT);
      end;
    end;
  {$else cpu64}
    // dumb type-casts on the 32-bit platforms
    function UnpackDwordToChepersyObjectReference (d: dword): TChepersyObject; inline;
    begin
      Result:= TChepersyObject(pointer(d));
    end;
    function PackChepersyObjectReferenceToDword (o: TChepersyObject): dword; inline;
    begin
      Result:= dword(pointer(o));
    end;
  {$endif cpu64}


Добавлено спустя 10 часов 23 минуты 54 секунды:
Заключил добавленную ещё, ЕМНИП, в 2004-м проверку "если на компе меньше 256 мегабайт оперативы - отказаться запускаться" в кондишналы, чтобы компилировалась только вместе с поддержкой легаси платформ (одноядерные процессоры под WinXP; процессоры не имеющие SSE2 под WinXP; Win98)
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 17.03.2020 17:48:07

Попробовал транк (3.3.1). Баг 33087 - словно Ленин, живее всех живых. Все варианты движка виснут при запуске.

С отвращением поглядел на гигантские протухшие туши выбросившихся на берег китов... А, не, это .so модуля под линукс и распбиан.
Попробовал сжать новейшим upx'ом. Матюгнулся также, как и upx 2013 года сборки:
upx: d:chentrahmoduleschentrahlib_hub-i686.so: CantPackException: DT_TEXTREL found; re-compile with -fPIC
ИЧСХ, ДЛЛы у меня уже собираются с -Cg, иначе они просто не работают.
Зачесалось воскресить утилиту brutalstrip и ободрать их... брутально. Есть у меня подозрение, что это просто strip тупит, тормозит и не смогает стрипнуть хтонические порождения Фри Паскаля. Десятилетие назад он так несмогал с виндовыми екзешниками, из-за чего я brutalstrip и создал. Утилитка выдирала все секции, которых не было в белом списке. А белый список я составлял методом тыка (отвинчивать по одной, пока не перестанет запускаться). ИЧСХ, екзешники худели просто волшебно.
Сейчас на екзешниках штатный стрип справляется, и на виндовых ДЛЛах тоже, после upx'а размер - в районе 450 килобайт. Но линёвые ДЛЛы - просто бельмо на глазу :x

Поставил в задачи на отдалённое будущее: сейчас времени на такую фигню нет.

Добавлено спустя 16 минут 30 секунд:
З.Ы. Похоже, виснет моя функция формата, причём, конкретно на обработке числительных.
Почему со старыми версиями компилятора не висло? :( Что-то я делаю не так.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение скалогрыз » 17.03.2020 20:27:16

Cheb писал(а):.Ы. Похоже, виснет моя функция формата, причём, конкретно на обработке числительных.
Почему со старыми версиями компилятора не висло? Что-то я делаю не так.

Пытаешься делать (сложное) всё и сразу! разбей по кускам. Завези отдельные тесты для функции формата, и тогда смена компилятора тебе будет не страшна.
скалогрыз
долгожитель
 
Сообщения: 1706
Зарегистрирован: 03.09.2008 02:36:48

Re: Cheb's Game Engine

Сообщение Cheb » 17.03.2020 20:49:34

The coding horror!
Изображение
Уже страшно подпускать себя к коду.
В одном месте локальную переменную забыл нулём инициализировать, в другом - вообще присвоить значение Result...
Компиляторы 2.6.4 и 3.1.1 - перемогали каким-то чудом. 3.3.1 - взял в руки хворостину :oops:

Исправил - 32-битная стала падать с воплем, что не могёт установить обработчик исключений. 64-битная - всё работает, падает, где положено (не доделано, ибо)
Какого...?

..А, не, всё верно. SetUnhandledExceptionFilter() возвращает, что предыдущего обработчика исключений НЕ БЫЛО. ??? :( То есть, фпц 3.3.1 для x86 не использует SEH?.. Что он тогда использует-то?.. :(
..Упс. Ничего Он не использует, вся обработка исключений в RTL заключена в кондишнл FPC_USE_WIN32_SEH (наверняка не установленный).
Ну, транк - на то и транк.

Вывод: вовремя я решил делегировать сборку 32-битной версии древнекомпилятору 2.6.4

Добавлено спустя 11 минут 59 секунд:
Угх, теперь у всех строк отрезается последний символ.
Убиться об стену, что-ль.

Добавлено спустя 3 часа 4 минуты 20 секунд:
А, не, это десятилетней свежести ляп в методе рендера консоли. Рисовалось на 2 символа меньше, чем надо, но поскольку в старой версии это всегда были игнорируемые #13#10... Баг на баг давал всё хорошо, прекрасная маркиза.

Добавлено спустя 11 часов 3 минуты 6 секунд:
Завези отдельные тесты для функции формата,

Нет! Настоящие джедаи всё делают на интуиции и внимательности! (и отладочных WriteLn)
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 20.03.2020 02:20:34

Потрясающий контраст.
Собранное 2.6.4 или 3.0.4 - полностью, 100% рабочий модуль.
Собранное 3.1.1 или 3.3.1 - глючащее месиво, крашащееся с каскадом исключений при обработке исключений.
Одна из причин - работа со строками окончательно скатилась в сраное говно.

Объединение нескольких строк через +, работающее в 3.0.4 с теми же {$codepage utf-8} и {$unicodestrings on}, в 3.3.1 генерирует какие-то хтонические кракозяблы. Да, там смесь UnicodeString и AnsiString, которую дают функции типа GetEnumName. Также, параметр функции, наивно объявленный, как string, добавляет хаоса. И все строковые константы компилятор считает UnicodeString, поднимая страшную вонь при сравнении их с Utf8String.

Но трешить содержимое строки в хлам при просто конкатенации?.. Это уже ниже плинтуса.

Добавлено спустя 6 часов 48 минут 4 секунды:
Медитирую ЧЯДНТ.

Добавлено спустя 1 час 19 минут 47 секунд:
Плюс, в 3.3.1 DLL'а однозначно устанавливает свой собственный SetUnhandledExceptionFilter. Проблема в том, что работает оный через анус: av пробивает сквозь все вложенные блоки try и ловится самым внешним блоком в методе Execute потока. Истинный адрес исключения - потерян, стек вызовов - потерян. Гадайте на кофейной гуще.

Добавлено спустя 1 час 11 минут 50 секунд:
Для справки: установленный модулем-маткой=00411060h, мой=00489320h, после загрузки ДЛЛ модуля=003EC989h

В предыдущих версиях фпц исключения в ДЛЛ вообще не ловились, т.к. ДЛЛ свой обработчик не ставила - см. баг №4605, зафиксированный в июне 2003-го и помеченный, как пофиксенный в 3.2

Буду модифицирорвать, агрессивно восстанавивая обработчик матки при загрузке модуля. И надо ещё не забыть, что всякие длл драйверов типа опенгля или винтаба при загрузке могли свои при загрузке доставить.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение runewalsh » 20.03.2020 17:01:46

У меня строки однажды навсегда сломались в одной из 3.* версий, и единственный способ, который я нашёл, чтобы их починить — хранить исходники в UTF-8 БЕЗ BOM, НЕ использовать {$codepage}, и в самом начале программы сделать DefaultSystemCodePage := CP_ACP. Это обусловлено тем, что без {$codepage} и BOM компилятор выставляет кодировку строковых литералов в CP_ACP, а кодировка динамически созданных строк (например, после SetLength) выставляется в DefaultSystemCodePage. Так что впоследствии при каком-либо совместном использовании динамических строк и литералов компилятор видит, что работает со строками с одинаковыми кодировками, и не устраивает самодеятельность. А, ну и да, при этом предполагается все строки считать (ansi)string'ами с байтами вместо символов, а не widestring'ами. {$codepage utf8} или BOM я не использую ещё и по той причине, что они превращают литералы с символами вне 7-битной ASCII в widestring'и.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 461
Зарегистрирован: 27.04.2010 00:15:25

Re: Cheb's Game Engine

Сообщение Cheb » 20.03.2020 19:09:20

{$codepage utf8} или BOM я не использую ещё и по той причине, что они превращают литералы с символами вне 7-битной ASCII в widestring'и.

Ну, для меня это не критично, т.к. русские буквы у меня встречаются только в мессагах, а мессаги всё равно обрабатываются, как Utf16String. Игра, гуй - у всего этого внутренний формат есть или будет утф-16: объём русского текста одинаковый, так и так два байта на букву, а обращение к строкам, как к массивам и мгновенно известная длина - удобно и производительно.

Пока остановился на следующем:
1. убрал {$modeswitch unicodestrings}
2. добавил в инициализацию матки и модуля
Код: Выделить всё
   {$if FPC_FULLVERSION>=30000}
     SetMultiByteConversionCodePage(CP_UTF8);
     SetMultiByteRTLFileSystemCodePage(CP_UTF8);
   {$endif}

3. планирую все конкатенации строк заменить на вызовы CgeFormat(<utf-16 строка с разметкой>,[<array of const>]), ибо заодно помогает код из каши превратить в читаемый.
4. планирую все встречающиеся в коде литералы завернуть в тайпкасты.

Уже ввёл в эксплуатацию:
- function RawByteStringsEqual(a, b: RawByteString): boolean , которой насрать на кодировку
-
Код: Выделить всё
  {$ifdef unix} //utf-8 assumed
   function AnsiToUtf16(a: AnsiString): Utf16String;
   begin
     Result:= Utf8Decode(a);
   end;
  {$else}
   function AnsiToUtf16(a: AnsiString): Utf16String;
   var
     i: integer;
   begin
     if a='' then Exit('')
     else
   {$ifdef CGE_PLATFORM_HAS_WINDOWS98}
     if (Mother^.State.OS in [ostWin98])
       and Mother^.State.Windows98.DoesNotSupportUnicode
       then Result:= Cp1251ToUtf16(a) // assuming Russian/CP1251
       else
   {$endif}     
     begin
       i:= MultiByteToWideChar(
                             CP_ACP, MB_PRECOMPOSED, @a[1], length(a), nil, 0);
       if i > 0 then begin
         SetLength(Result, i);
         MultiByteToWideChar(
                      CP_ACP, MB_PRECOMPOSED, @a[1], length(a), @Result[1], i);
       end
       else begin
         if Mother^.State.OS in [ostWin98, ostWin2k]
           then Result:= Cp1251ToUtf16(a)
           else Die('MultiByteToWideChar() failed!');
       end;
     end;
   end;
  {$endif}
{$endif}


Добавлено спустя 16 часов 56 минут 13 секунд:
Не могу понять, как это работает в 3.3.1. RTL модуля гарантированно не ставит своего обработчика SEH и это точно не VEH, в длл даже нет байндингов. Поток логики вызывает AV, мой обработчик НЕ вызывается, какая-то неведомая сила передаёт исключение самому внешнему блоку try в методе Execute потока.

Добавлено спустя 54 минуты 12 секунд:
Откладываю поддержку транка и x86_64 до осени. Продолжу разработку на 3.0.4 и 2.6.4.

Добавлено спустя 6 часов 39 минут 5 секунд:
Вопрос ЧЯДНТ таки стоит: наваял голый тест, фпц 3.3.1 исключения в ДЛЛ таки ловит, ПРИЧЁМ правильно (срабатывает самый внутренний блок), ПРИЧЁМ, даже если екзешник собран в 2.6.4 (т.е. ставит обработчик SEH). ИЧСХ, екзешник, собранный 3.3.1 обработчика SEH не ставит, от слова совсем.

Не может быть так, что мне драйвера подгадили? Драйвер графического планшета точно ставит свой обработчик.

Код: Выделить всё
program thrtesta;
{$mode objfpc}
{$apptype console}
{$longstrings on}
uses
{$ifdef unix}
  cthreads,
{$endif}
  SysUtils,
  Classes
  {$ifdef unix}
    , dl
  {$else}
    , windows
  {$endif}
  ;
type
  TTestThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  procedure TTestThread.Execute;
  begin
    WriteLn('> A');
    try
      byte(nil^):= 0;
    except
      WriteLn('exe thread ID=',GetCurrentThreadId()
        ,' catch: ',(ExceptObject as Exception).Message);
    end;
    WriteLn('< A');
  end;
 
  function PCharToString(P: PAnsiChar): Utf8String;
  var
    i: integer;
    p2: PAnsiChar;
  begin
    if not Assigned(p) then Result:= ''
    else begin
      p2:= p;
      i:= 0;
      While p2^ <> #0 do begin
        inc(p2);
        inc(i);
      end;
      SetLength(Result, i);
      MOVE(p^, Result[1], i);
    end;
  end; 

var
  t: TTestThread;
  dllhandle: {$ifdef unix} pointer {$else} THandle {$endif};
  mypath: string;
  {$ifdef unix}
    ufn, upn: Utf8String;
  {$else}
    wfn: UnicodeString;
    wpn: AnsiString;
  {$endif}
  thrproc: procedure; cdecl = nil;
 
begin
  WriteLn('the exe is built using fpc '
    ,{$I %FPCVERSION%},'/',{$I %FPCTARGETOS%},'/',{$I %FPCTARGETCPU%});
  WriteLn('main thread ID=', GetCurrentTHreadId());         
  t := TTestThread.Create(False);
  WriteLn('exe thread created'); 
  try
    t.WaitFor;
  finally
    t.Free;
  end;
  WriteLn('exe thread terminated');
  WriteLn('loading the DLL...');
  mypath:= ExtractFilePath(ParamStr(0))
    + {$ifdef unix} 'libthrtestb.so' {$else} 'thrtestb.dll' {$endif};
  WriteLn('path is ', mypath);
  {$ifdef unix}
    ufn:= mypath; 
    dllhandle:= dlopen(PAnsiChar(nu8), RTLD_NOW);
    if not Assigned(DLL) then begin
      WriteLn('failed to load: ',PCharToString(dlerror()));
      Halt(0);
    end;
    upn:= 'thrproc';
    pointer(thrproc):= dlsym(dllhandle, PAnsiChar(upn));
  {$else}
    wfn:= mypath;
    SetLastError(0);
    dllhandle:= LoadLibraryW(PUcs2Char(wfn));
    if dllhandle = 0 then begin
      WriteLn('failed to load.');
      Halt(0);
    end;
    wpn:= 'thrproc';
    pointer(thrproc):= windows.GetProcAddress(dllhandle, PAnsiChar(wpn));
  {$endif}
  if not Assigned(pointer(thrproc)) then begin
    WriteLn('failed to load the procedure.');
    Halt(0);
  end;

  WriteLn('invoking the dll...');
  try
    thrproc;
  except
    WriteLn('exe thread ID=',GetCurrentThreadId()
      ,' catch: ',(ExceptObject as Exception).Message);
  end;
  WriteLn('unloading the dll...');
  {$ifdef unix}
    dlClose(dllhandle);
  {$else}
    FreeLibrary(dllhandle);
  {$endif}
  WriteLn('done.');
end.


Код: Выделить всё
library thrtestb;
{$mode objfpc}
{$apptype console}
{$longstrings on}
uses
{$ifdef unix}
  cthreads,
{$endif}
  SysUtils,
  Classes;
type
  TTestThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  procedure TTestThread.Execute;
  begin
    WriteLn('> X');
    try
      WriteLn('> Y');
      try
        WriteLn('> Z');
        try
          byte(nil^):= 0;
        except
          WriteLn('dll thread ID=',GetCurrentThreadId()
            ,' catch in block Z: ',(ExceptObject as Exception).Message);
        end;
        WriteLn('< Z');
      except
        WriteLn('dll thread ID=',GetCurrentThreadId()
          ,' catch in block Y: ',(ExceptObject as Exception).Message);
      end;
      WriteLn('< Y');
    except
      WriteLn('dll thread ID=',GetCurrentThreadId()
        ,' catch in block X: ',(ExceptObject as Exception).Message);
    end;
    WriteLn('< X');
  end;

  procedure MyMainProc; cdecl;
  var t: TThread;
  begin
    WriteLn('the dll is built using fpc '
      ,{$I %FPCVERSION%},'/',{$I %FPCTARGETOS%},'/',{$I %FPCTARGETCPU%});
    try
      t := TTestThread.Create(False);
      WriteLn('dll thread created'); 
      try
        t.WaitFor;
      finally
        t.Free;
      end;
    except
      WriteLn('dll thread ID=',GetCurrentThreadId()
        ,' catch in main proc: ',(ExceptObject as Exception).Message);
    end;
    WriteLn('the dll is done.')
  end;
 
exports
  MyMainProc name 'thrproc';
begin
// do nothing.
// The initialization sections DO NOT WORK in Linux for DLLs. And never will.
end.


3.0.4: закономерный хряп
the exe is built using fpc 3.0.4/Win32/i386
main thread ID=6444
exe thread created
> A
exe thread ID=6736 catch: Access violation
< A
exe thread terminated
loading the DLL...
path is d:chentrahmodulesteststhrtestb.dll
invoking the dll...
the dll is built using fpc 3.0.4/Win32/i386
dll thread created
> X
> Y
> Z
An unhandled exception occurred at $1000165F:
EAccessViolation: Access violation
$1000165F
$100173C5
$1000BE1E
$75E6343D
$76F39802
$76F397D5


3.3.1: летает безо всяких костылей
the exe is built using fpc 2.6.4/Win32/i386
main thread ID=780
exe thread created
> A
exe thread ID=6232 catch: Access violation
< A
exe thread terminated
loading the DLL...
path is d:chentrahmodulesteststhrtestb.dll
invoking the dll...
the dll is built using fpc 3.3.1/Win32/i386
dll thread created
> X
> Y
> Z
dll thread ID=6076 catch in block Z: Access violation
< Z
< Y
< X
the dll is done.
unloading the dll...
done.


Добавлено спустя 16 часов 10 минут 59 секунд:
Всё в 3.3.1 работает, а я дятел. Долбический.
Инициализация СУБД не была завёрнута ни в одит блок try кроме основного блока логического треда, который сигналит "Шеф, усё пропало!"

Образно говоря, самоотладка у меня организована так:
Код: Выделить всё
try
  Найти шкаф;
  try
    Открыть дверцу;
    try
      Взять варенье;
      try
         Открыть банку;
      except
        Die('Банка хряпнулась :(... ');
      end;
    except
      Die('Варенью йок.');
    end;
  except
    Die('Трагедия при открытии шкафа!');
  end;
except
  Die('Шкаф упал!');
end;


Где процедура Die занимается всей черновой работой: если это её первый вызов - вынимает детали из ExceptObject и составляет стек вызовов. Иначе просто добавляет сообщение в список.

В итоге имеем что-то типа

Песец!
Шкаф упал!
Трагедия при открытии шкафа!
Варенью йок.
Access Violation по адресу...
Стек вызовов:
...

Добавлено спустя 12 минут 39 секунд:
Изображение

По любому до осени, т.к. в 3.2 сильно изменился формат RTTI и мне нужно долго, нудно адаптировать регистрацию типов в Чеперси.

Закукливаюсь на 3.0.4 @ x86/Win32.


Изображение
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Сквозняк » 13.04.2020 21:09:21

Ну и стоило заниматься такой жуткой оптимизацией? Это же антипаскалеский принцип. Приходится использовать ненадёжные системные фичи, которые паскаль старается обходить стороной. В результате список платформ уменьшается, а баги и трудозатраты увеличиваются. А тем временем 32 битная платформа на х86 превращается в наследие. Чем больше крови пьёт бодание с системой, тем меньше сил остаётся на саму игру.
Сквозняк
энтузиаст
 
Сообщения: 762
Зарегистрирован: 29.06.2006 22:08:32

Re: Cheb's Game Engine

Сообщение Seenkao » 14.04.2020 14:37:14

Я уж извиняюсь, но внесу свою лепту.
Скачал, запустил... и удалил...
Большой плюс тебе за терпение! За знания которые ты получаешь! Это всегда полезно. :)
Но... запуская демку, на i5... и фпс скачет 27-40 (в основном 27)... нет, проще использовать Castle Game Engine. Думаю большую библиотеку сложно перелопатить, а наверняка где-то куча вещей, которые незаметно тормозят систему.
Seenkao
новенький
 
Сообщения: 42
Зарегистрирован: 01.04.2020 03:37:12

Re: Cheb's Game Engine

Сообщение Cheb » 21.04.2020 14:34:07

Автором этого сообщения является Сквозняк, находящийся в вашем чёрном списке. Показать это сообщение.

Я не комментирую спам. Всего хорошего.

Но... запуская демку, на i5... и фпс скачет 27-40 (в основном 27)...

Хаха, сразу видно - тему не читал :mrgreen:
В режиме меню фпс ограничивается до 30 (с целью ограничения потребления энергии и износа вентиляторов), Но ограничение подскакивает до 60 при быстрых движениях мышью (больше 5 пикселов за кадр), чтобы обеспечить плавное движение указателя. На практике, при шевелении мышью фпс скачет.
И даже в игровом режиме, мой движок *вообще* не позволит фпс подняться выше примерно 80. Там в правом нижнем углу диаграммы профайлера, показывающие какую долю времени кадра он спит :mrgreen:

Добавлено спустя 18 минут 25 секунд:
По ходу, успешно адаптировал к 3.2.0-rc1, объём необходимых адаптаций оказался смешным. См. соотв. тему.
Засада была с array of const: если одним из параметров в него передать shortstring, полученную из мусорного указателя (напрример, из косорукой интерпретации RTTI), то код вызова не падает, а берёт сам мусорный указатель и делает из него битую TVarRec, и падение происходит уже в недрах функции, у которой в параметрах тот злосчастный array of const.

А у меня это было в блоке, генерирующем сообщение об ошибке. Который сам падал и я получал на выходе тыкву.

Над движком работать почти некогда. Работа по профилю, потом решил посмотреть, чем славны Roster Teeth. RWBY, конечно, миленько - но их 2d мультики Camp Camp и Nomad of Nowhere - более душевные и забавные.

Добавлено спустя 3 минуты 47 секунд:
P.S. Те люди, что в своих движках позволяют в меню / экранах загрузки зашкаливающий фпс типа 400 - просто скоты, которым плевать на экологию и расходы пользователя. Потому что любой компьютер изнашивается гораздо быстрее под полной нагрузкой.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 825
Зарегистрирован: 06.06.2005 15:54:34

Пред.След.

Вернуться в Разработки на нашем сайте

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 3

Рейтинг@Mail.ru