Исправил ещё один баг в Чеперси: неправильно угадывала как компилятор размещает поля - статические массивы из элементов в 1 и 2 байта.
Добавлено спустя 5 часов 36 минут 15 секунд:Забраковал ранее наработанное (кроме разрежённого массива).
Не будет ограничений на количество слоёв. Это будет древовидная структура произвольной формы. У родительского любое количество дочерних.
Дополнительное ограничение: дочерний слой должен тикать синхронно с родительским. Потом может тикать сам ещё любое число раз. Не может отставать или воздерживаться.
Экземпляры классов не будут хранить, к какому слою они принадлежат. Будут лишь иметь счётчик ссылок.
Фактически, то что я делаю - это костыли для придания классам свойства CopyOnWrite со счётчиком ссылок.
Состоялся губозакатывательный сеанс №2. Слои альтернативной реальности будут расползаться, как раковая опухоль. Расслаиваясь в любом месте, где у родителя или у потомка произошло изменение. Или лечить это механизмом сличения контрольных сумм и "схлопывания" идентичных объектов?
Неее, нуегона. Пусть все слои, кроме базового, будут короткоживущими.
По любому, если поставить перманентное заклинание "здесь не дверь, здесь стенка", то через раздавленных бабочек ИИ близбежавшего зайца это отличие передастся дальше, и через какое-то время будем иметь две полные копии игрового мира, работающие параллельно.
Вывод: иллюзии должны быть или короткими (полторы минуты максимум), или работать на другом принципе, альтернативной чисто визуальной составляющей.
Добавлено спустя 11 часов 19 минут 49 секунд:В связи с заявленной кончиной
GetVersionEx , накатал/скопипастил целую простыню для опознания ОС на основе
VerifyVersionInfo(), коя заявлена современной и появилась ещё в Windows 2000. Пристегнул к экзешнику манифест, скопипащенный с
https://msdn.microsoft.com/en-us/librar ... 85%29.aspx .
И что бы вы думали? Win32MajorVersion / WIN32MinorVersion показали 10.0.
Но паскаль-то их выставляет, вызывая GetVersionEx() !
Т.е. врут собаки, зря трудился
З.Ы. В десятке работает плавно, но с секундным подвисанием при переключении с 2 на 3 (ускоренную промотку). На индикаторе при этом мелькает, что основной поток ждёт синхронизации. Но после, когда всё становится плавным, основная его нагрузка - спит! А в семёрке - вся нагрузка всегда окрашена в ждёт синхронизации.
Отрадно, что починили взад, но теперь мне отлаживать синхронизацию потоков в трёх осях: XP, 7 и 10, и в каждой оно ведёт себя серьёзно по разному.
- Код: Выделить всё
{$ifdef windows}
function GetLocalAppDataDir: TFileNameString; forward;
{
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451%28v=vs.85%29.aspx
[GetVersionEx may be altered or unavailable for releases after Windows 8.1.
Instead, use the Version Helper APIs]
With the release of Windows 8.1, the behavior of the GetVersionEx API has
changed in the value it will return for the operating system version. The value
returned by the GetVersionEx function now depends on how the application
is manifested.
Applications not manifested for Windows 8.1 or Windows 10 will return the
Windows 8 OS version value (6.2). Once an application is manifested for a given
operating system version, GetVersionEx will always return the version that the
application is manifested for in future releases.
}
function DetectWindowsNTVersion(): TOSType;
{$if defined(win32) and (FPC_FULLVERSION<20700)}
type
OSVersionInfoEX = record
dwOSVersionInfoSize : DWORD;
dwMajorVersion : DWORD;
dwMinorVersion : DWORD;
dwBuildNumber : DWORD;
dwPlatformId : DWORD;
szCSDVersion : array[0..127] of AnsiChar;
wServicePackMajor : WORD;
wServicePackMinor : WORD;
wSuiteMask : WORD;
wProductType : BYTE;
wReserved : BYTE;
end;
var
VerifyVersionInfo: function(
var lpVersionInfo: OSVersionInfoEX;
dwTypeMask: dword;
dwlConditionMask: qword
): boolean; stdcall;
VerSetConditionMask: function(
dwlConditionMask: qword;
dwTypeBitMask: dword;
dwConditionMask: byte
): qword; stdcall;
// ULONGLONG WINAPI VerSetConditionMask(
// _In_ ULONGLONG dwlConditionMask,
// _In_ DWORD dwTypeBitMask,
// _In_ BYTE dwConditionMask
// );
//BOOL WINAPI VerifyVersionInfo(
// _In_ LPOSVERSIONINFOEX lpVersionInfo,
// _In_ DWORD dwTypeMask,
// _In_ DWORDLONG dwlConditionMask
//);
dll: THandle;
p: pointer;
const
VER_MAJORVERSION = $0000002;
VER_MINORVERSION = $0000001;
VER_GREATER_EQUAL = 3;
function LoadProcAddress(hdll: THandle; ProcName: ansistring) : pointer;
var
baseaddr: pointer;
exename: UnicodeString;
begin
Result:= GetProcAddress(hdll, PChar(ProcName));
if Assigned(Result) then begin
GetModuleByAddr(Result, baseaddr, exename);
VerboseLog(' %0() at %1 in %2', [ProcName, Result, exename]);
end
else
VerboseLog(' %0() not found!', [ProcName]);
end;
{$endif}
function IsOrGreater(wMajorVersion, wMinorVersion: Word): Boolean;
var
osvi: OSVersionInfoEX;
dwlConditionMask: qword;
begin
FillChar(osvi, sizeof(osvi), 0);
osvi.dwOSVersionInfoSize := SizeOf(osvi);
osvi.dwMajorVersion := wMajorVersion;
osvi.dwMinorVersion := wMinorVersion;
dwlConditionMask := VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
Result := VerifyVersionInfo(osvi, VER_MAJORVERSION or VER_MINORVERSION, dwlConditionMask);
end;
begin
Result:= ostWin2k;
try
VerboseLog( 'Detecting Windows NT version...');
{$if defined(win32) and (FPC_FULLVERSION<20700)}
VerboseLog(' loading kernel32.dll...');
dll:= LoadLibrary('kernel32.dll');
p:= LoadProcAddress(dll, 'VerifyVersionInfoA');
if not Assigned(p) then Exit;
pointer(VerifyVersionInfo):= p;
p:= LoadProcAddress(dll, 'VerSetConditionMask');
if not Assigned(p) then Exit;
pointer(VerSetConditionMask):= p;
{$endif}
if IsOrGreater(5, 1) then Result:= ostWinXP;
if IsOrGreater(6, 0) then Result:= ostVista;
if IsOrGreater(6, 1) then Result:= ostWin7;
if IsOrGreater(6, 2) then Result:= ostWin8;
if IsOrGreater(6, 3) then Result:= ostWin81;
if IsOrGreater(10, 0) then Result:= ostWin10;
except
end;
end;
{$endif}
procedure DetectOSType;
begin
VerboseLog('Detecting operating system...');
{$ifdef unix}
{$ifdef darwin}
Mother^.State.OS:= ostMacOSX;
{$else}
Mother^.State.OS:= ostLinux;
{$endif}
{$else}
if RunningInWine then begin
Mother^.State.OS:= ostWine;
Mother^.State.DriveZIsRoot:= GetZIsRoot();
if Mother^.State.DriveZIsRoot then begin
//otherwise we're unable to tell Linux from MacOS X
if FileExists('z:usrliblibc.dylib')
then Mother^.State.OS:= ostDarwine;
end;
end
else
if _RunningInWindows98 then begin
Mother^.State.OS:= ostWin98; //98 or Me
VerboseLog(' It''s Windows 98 or Millennium, v%0.%1.', [Win32MajorVersion, WIN32MinorVersion]);
end
else begin
VerboseLog(' It''s Windows NT %0.%1.', [Win32MajorVersion, WIN32MinorVersion]);
case Win32MajorVersion of
3,4: Mother^.State.OS:= ostWin2k; //Windows NT 3.x and 4.x are treated as Windows 2000. Chentrah probably won't event start there
{ 5: if WIN32MinorVersion = 0
then Mother^.State.OS:= ostWin2k
else Mother^.State.OS:= ostWinXP; //or server 2003, doesn't matter
6: case WIN32MinorVersion of
0: Mother^.State.OS:= ostVista;
1: Mother^.State.OS:= ostWin7;
2: Mother^.State.OS:= ostWin8;
else
Mother^.State.OS:= ostWin8;
end;
}
else
Mother^.State.OS:= DetectWindowsNTVersion();
end;
end;
Mother^.State.CSIDL_AppDataDir:= GetLocalAppDataDir;
VerboseLog(' Local app data directory is %0', [GetLocalAppDataDir]);
Mother^.State.Windows98.DoesNotSupportUnicode:= {$ifdef cpu64} false {$else} not CheckIfWindows98HasUnicodeSupportInstalled() {$endif} ;
{$endif}
Mother^.State.OstID:= GetEnumName(typeinfo(TOSType), ord(Mother^.State.OS));
if Mother^.State.OS = ostWine
then Mother^.State.OSName:= WineVersionString
else begin
// if (Win32MajorVersion < 5) or (Win32MajorVersion > 6)
// or ((Win32MajorVersion = 6) and (WIN32MinorVersion > 1))
// then Mother^.State.OSName:= 'Windows NT ' + IntToStr(Win32MajorVersion) + '.' + IntToStr(WIN32MinorVersion)
// else
Mother^.State.OSName:= OSDisplayedName[Mother^.State.OS];
end;
{$ifdef unix}
{$ifndef darwin}
DetectLinuxVersionString;
{$endif}
{$endif}
end
Добавлено спустя 2 минуты 34 секунды:З.Ы. Пробовал я эти их сраные
Version Helper functions. Нету их! По крайней мере, GetProcAddress() их не находит. Возможно, это вообще макросы в сишных хидерах.
- Код: Выделить всё
Detecting operating system...
Trying to detect Wine...
..system directory is C:\WINDOWS\system32
..trying to open C:\WINDOWS\system32\kernel32.dll for read...
..scanning for signature string "Wine placeholder DLL"...
..detected = false
It's Windows NT 6.2.
Trying to detect if this is Windows 8.0 or greater...
loading kernel32.dll...
IsWindows8Point1OrGreater() not found!
Добавлено спустя 3 минуты 8 секунд:З.З.Ы. При отсутствии правильного манифеста, десятка, как и заявлено, тщательно прикидывается восьмёркой.