Перейти к содержимому


Фотография
* * * * * 1 Голосов

WTD


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 54

#21 Dageron

Dageron

    Активный участник

  • Пользователи
  • PipPipPip
  • 1130 сообщений
  • Пол:Мужчина
  • Город:Пермь


Отправлено 27 August 2009 - 12:32

С mip-ами у RussianCJ все должно быть нормально, для конверта TXD->WTD не нужны уровни.

А вот насчет флагов то ошибка здесь очень вероятна. Расчет был сделан через старую функцию из составляющих-размеров.
Тут честно говоря идеи корректности иссякают, надо разбирать побитную структуру. Если память мне не изменяет, то она определяется как:
Paged :1;
Compressed :1;
CPUSize :4; //RealCPUSize=2^(CPUSize+8);
CPUPageCount :11;
GPUSize :4; //RealGPUSize=2^(GPUSize+8);
GPUPageCount: 11;
(число после ":" количество бит, которые отводятся на значение)
Если рассчитать CPUSize и GPUSize можно, подставить compressed и paged можно то что делать с количествами страниц?
в проекте gtamodding.ru: декабрь 2008 - декабрь 2012

#22 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 27 August 2009 - 13:24

Со страницами так (дубль пятый): Там не одно поле в 11 бит, а пять полей: одно - 7 бит и четыре по одному биту. (назовем их largeCount и smallPage2, smallPage4, smallPage8 и smallPage16) Ресурс состоит из страниц. В начале идет largeCount страниц по (1 << (Size+12)) байт. Затем, если smallPage2 == 1, страница размером (1 << (Size+11)) Потом, если smallPage4 == 1 - страница размером (1 << (Size+10)) Аналогично - для smallPage8 и smallPage16. Все страницы выделяются независимо и, при работе, могут перемещаться в памяти (в целях дефрагментации). Т.е., если какая-то структура пересекает границу страницы, то, если страницы выделены не подряд, вместо "хвоста" этой структуры, будут читаться произвольные данные.
You think your day was surreal? Try mine.

#23 Dageron

Dageron

    Активный участник

  • Пользователи
  • PipPipPip
  • 1130 сообщений
  • Пол:Мужчина
  • Город:Пермь


Отправлено 28 August 2009 - 03:50

Так, интересно.

Вот моя структура значения флагов:
typedef struct Flags
{
	int Paged :1;
	int Compressed :1;
	int CPUSize:4; //RealCPUSize=2^(CPUSize+8);
	int CPULargeCount:7;
	int CPUSmallPage2:1;
	int CPUSmallPage4:1;
	int CPUSmallPage8:1;
	int CPUSmallPage16:1;
	int GPUSize:4; //RealGPUSize=2^(GPUSize+8);
	int GPULargeCount:7;
	int GPUSmallPage2:1;
	int GPUSmallPage4:1;
	int GPUSmallPage8:1;
	int GPUSmallPage16:1;
};

Чтобы реализовать чтение через Delphi/C++, привожу пример из pgBase.cpp:
WORD   vpageCount = dwRscFlags & 0x7FF;			// virtual memory block page count
	WORD   largeVpageCount = vpageCount >> 4;
	DWORD   vpageSize = ((dwRscFlags >> 11) & 15)+8;
	WORD   ppageCount = (dwRscFlags >> 15) & 0x7FF;	// physical memory block page count;
	WORD   largePpageCount = ppageCount >> 4;
	DWORD   ppageSize = ((dwRscFlags >> 26) & 15)+8;
С побитовым чтением проблем возникнуть не должно, сейчас думаю как действовать с записью. Если даже не делать оптимальную раскладку структур по блокам, пока что появляется слишком много непоняток.

Вот допустим имеется часть памяти размером 4096.

Size = log2(4096-12); //Надо ли еще где-то использовать оригинальный размер, или же везде Size?
LargePageSize = (1<<(Size)); //Это значение должно быть округлено до кратного двум, вверх.
LargeCount = (Size/(LargePageSize)); //Целочисленное деление
Далее, Size-LargePageSize надо разделять на маленькие страницы?
в проекте gtamodding.ru: декабрь 2008 - декабрь 2012

#24 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 28 August 2009 - 11:29

1 << (Size+12) что-то я не понимаю, как это выражение работает...

#25 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 28 August 2009 - 15:56

Size = log2(4096-12)

-12 - это лишнее. 12 байт заголовка в размеры не входят, а размер страницы всегда должен быть степенью двойки.

Вообще, запись - это принципиально другой уровень.
Раскладка блоков по страницам с минимизацией потерь места и количества страниц - типичная задача динамического программирования. Я, для простоты, брал жадный алгоритм - он не самый оптимальный, но простой и дает приемлемые результаты.

В том же pgBase должно быть описание. Если нет - попробую объяснить так.

1 << (Size+12)

Битовый сдвиг влево. Например, для Size = 1, это будет 10000000000000b = 0x2000 = 8192
You think your day was surreal? Try mine.

#26 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 28 August 2009 - 16:44

1 << (Size+12)

Битовый сдвиг влево. Например, для Size = 1, это будет 10000000000000b = 0x2000 = 8192

То есть, чтобы получить одну большую страницу, надо округлять размер ресурса до размера, кратного 8192?

#27 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 28 August 2009 - 17:22

Нет. До степени двойки (4096/8192/16384/32768/...)
You think your day was surreal? Try mine.

#28 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 28 August 2009 - 17:36

Тогда минимальным размером страницы может быть 256 байт. А если останется блок меньше этого размера, например, в GPU части?

#29 Dageron

Dageron

    Активный участник

  • Пользователи
  • PipPipPip
  • 1130 сообщений
  • Пол:Мужчина
  • Город:Пермь


Отправлено 28 August 2009 - 17:46

Тогда (как я понял), этот блок пойдет на smallPages.
в проекте gtamodding.ru: декабрь 2008 - декабрь 2012

#30 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 28 August 2009 - 17:57

но ведь есть только 5 типов размеров страниц...и как я понял, самая маленькая страница может быть 1 << 8 = 256 байт

#31 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 28 August 2009 - 18:51

В файле должна обязательно присутствовать хотя бы одна large page. Т.е., меньше 4К (в распакованном виде) файл быть не может. Самая маленькая small page - действительно, 256 байт.
You think your day was surreal? Try mine.

#32 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 28 August 2009 - 19:16

ну, предположим, что размер CPU равен 4096 байт, а GPU - 520 байт. Понятно, что будет одна большая страница (4096 байт) в CPU и маленькая (512 байт) в GPU...но ведь в GPU остаются ещё 8 байт...что с ними делать?

#33 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 28 August 2009 - 19:33

Нет, будет две большие страницы (по 4К) - на каждую часть (CPU/GPU) страницы считаются отдельно. Если же требуется в одну часть уместить две структуры (4К и 520 байт) - это будет одна большая страница (4К) и одна страница в 1К. 508 байт - потери.
You think your day was surreal? Try mine.

#34 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 29 August 2009 - 01:45

Я нашёл вот эту схему и появилось пару вопросов:
1) В том же ли порядке показаны биты, если на них смотреть через 010 Editor? Я просто посмотрел на примере смены флагов страничности и сжатости от GooD'а и заметил, что биты меняются совсем с другой стороны.
2) Какой размер страницы надо ставить по той же схеме? Ведь существует 5 размеров страниц.

#35 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 29 August 2009 - 02:16

Схема правильная. Самый младший бит на ней - справа. Что касается размеров... Там применяется очень красивое решение: есть два метода рассчета размеров: один простой (если нужно быстро посчитать общий размер или распаковать все одним кусочком) второй - сложный (если нужно распаковать постранично). В простом методе мы берем размер (M) как одно число со всеми 11-ю битами, а в сложном - как пять чисел (одно (L) - 7 старших бит и четыре (S2..S16) - по одному). если посмотреть внимательно, M << (Size+8) == (L << (Size+12)) + (S2 << (Size+11)) + (S4 << (Size+10)) + (S8 << (Size+9)) + (S16 << (Size + 8)) Задавать размер можно по любой схеме, но нужно учитывать, что L должно быть больше 0 (т.е. M > 0x10) Я, в общей сложности, разбирался с этим порядка месяца. Когда понял, как оно работает - слегка прифигел от красоты решения.
You think your day was surreal? Try mine.

#36 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 29 August 2009 - 02:53

В простом методе мы берем размер (M) как одно число со всеми 11-ю битами

Но ведь на размер отводится всего 4 бита, но на количество - 11 бит...

#37 listener

listener

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 356 сообщений
  • Пол:Мужчина
  • Город:Ft.Lauderdale


Отправлено 29 August 2009 - 08:28

Здесь и имеются в виду эти 11 (они же 7+4*1) бит (вообще, во избежание путаницы, стоило бы говорить не "количество и размер" а "мантисса и порядок")

Сообщение отредактировал listener: 29 August 2009 - 08:38

You think your day was surreal? Try mine.

#38 Dageron

Dageron

    Активный участник

  • Пользователи
  • PipPipPip
  • 1130 сообщений
  • Пол:Мужчина
  • Город:Пермь


Отправлено 30 August 2009 - 07:43

RussianCJ
Ты как в своей программе располагал SimpleCollection (список хешей) и PtrCollection (список оффсетов на grcTexturePC) - до основных grcTexturePC или после? Очень странно, моя программа округляет размеры сегментов до числа, кратного 4096 и располагает SimpleCollection/PtrCollection перед grcTexturePC. Не знаю почему, но такой wtd-файл не читается (вылет игры), причем все существующие просмотрщики просматривают нормально. В структурах ошибок нет.

Интересно проследить как происходит сбор *.wtd-файла в G-Texture. Почему-то размер CPU-части округляется padding-ом до 8192 когда можно округлить до 4096. SimpleCollection/PtrCollection после grcTexturePC. Только вот какая в этом логика?
в проекте gtamodding.ru: декабрь 2008 - декабрь 2012

#39 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 30 August 2009 - 14:08

Я пробовал по разному располагать эти коллекции: до и после grcTexturePC, даже пробовал менять их местами, но разницы в игре не было никакой. Вылет игры у меня возникал только когда неправильно посчитан BytesPerLine.

#40 RussianCJ

RussianCJ

    Активный участник

  • Пользователи
  • PipPipPip
  • 54 сообщений

Отправлено 30 August 2009 - 15:39

Попробовал поставить флаг страничности (последний бит во флагах заменил на единицу)...теперь объект вообще не появляется




Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных