2009-11-13 5 views
3

Мне нужно как можно более загружать большие модели и другие структурированные двоичные данные на более старую игровую консоль на компакт-дисках. Каков наилучший способ сделать это? Данные будут экспортированы из приложения Python. Это довольно сложный проект для хобби.Загрузка файла с оптимальным файлом данных на игровой консоли

Requierements:

  • не полагаться на полностью стандартный STL совместимый - я мог бы использовать USTL хотя.
  • как немного накладные расходы как возможно. Стремитесь к решению так хорошо. что он может быть использован на оригинальной Playstation, и, тем не менее, как можно более современный и элегантный.
  • нет обратный/передний совместимость необходимо.
  • не копирует большие куски вокруг - предпочтительно файлы загружаются в ОЗУ в фоновом режиме, и все большие куски доступны непосредственно оттуда позже.
  • не должен полагаться на цель, имеющую одинаковую согласованность и выравнивание, то есть плагин C в Python, который выгружает свои структуры на диск, не будет очень хорошей идеей.
  • должен позволять перемещать загруженные данные, так как с отдельными файлами 1/3 размер ОЗУ, фрагментация может быть проблемой. Нет MMU, чтобы злоупотреблять.
  • робастность - отличный бонус, так как мой охват внимания очень короткий, то есть я бы сэкономил часть кода и забыл загрузку или наоборот, так что, по крайней мере, немой гарантией было бы хорошо.
  • Возможность обмена между загруженными данными и данными, полученными во время выполнения, без накладных расходов и без серьезных проблем с управлением памятью будет хорошим бонусом.

I рода имеет пол-план разбора в Python заголовках тривиального, ограниченный синтаксис C, который будет использовать структуры со смещением вместо указателей, и удобство оболочки Структура/классы в главном приложении с добытчиками, переводящий смещения для правильного ввода указателей/ссылок, но я хотел бы услышать ваши предложения.

Уточнение: запрос в основном касается структуры загрузки данных и проблем управления памятью.

ответ

3

Это модель развития общей игры ,

Обычный подход заключается в том, чтобы готовить данные на автономном этапе предварительного процесса. Полученные капли могут быть потоковыми с минимальными накладными расходами. Блоки зависят от платформы и должны содержать правильное выравнивание & endian-ness целевой платформы.

Во время выполнения вы можете просто нарисовать указатель на файл blob в памяти. Вы можете иметь дело с вложенными структурами. Если вы сохраняете оглавление со смещениями ко всем значениям указателя в блоке, вы можете исправить указатели, указывая на правильный адрес. Это похоже на работу dll.

Я работаю над библиотекой ruby, bbq, которую я использую для подготовки данных для своей игры в iphone.

Вот раскладка памяти я использую для больших двоичных объектов заголовка:

// Memory layout 
// 
// p begining of file in memory. 
// p + 0 : num_pointers 
// p + 4 : offset 0 
// p + 8 : offset 1 
// ... 
// p + ((num_pointers - 1) * 4) : offset n-1 
// p + (num_pointers * 4) : num_pointers // again so we can figure out 
//           what memory to free. 
// p + ((num_pointers + 1) * 4) : start of cooked data 
// 

Вот как я загрузить двоичный файл блоб и исправить указатели:

void* bbq_load(const char* filename) 
{ 
    unsigned char* p; 
    int size = LoadFileToMemory(filename, &p); 
    if(size <= 0) 
     return 0; 

    // get the start of the pointer table 
    unsigned int* ptr_table = (unsigned int*)p; 
    unsigned int num_ptrs = *ptr_table; 
    ptr_table++; 

    // get the start of the actual data 
    // the 2 is to skip past both num_pointer values 
    unsigned char* base = p + ((num_ptrs + 2) * sizeof(unsigned int)); 

    // fix up the pointers 
    while ((ptr_table + 1) < (unsigned int*)base) 
    { 
     unsigned int* ptr = (unsigned int*)(base + *ptr_table); 
     *ptr = (unsigned int)((unsigned char*)ptr + *ptr); 
     ptr_table++; 
    } 

    return base; 
} 

Моя bbq библиотека не совсем готова к прайм-тайм, но это может дать вам некоторые идеи о том, как писать их самостоятельно на питоне.

Удачи!

0

Рассмотрите возможность хранения данных в виде BLOB в SQLite DB. SQLite чрезвычайно портативен и имеет большой вес, ANSI C имеет интерфейсы C++ и Python. Это позаботится о больших файлах, отсутствии фрагментации, записи переменной длины с быстрым доступом и т. Д. Остальное - это просто сериализация структур для этих BLOB.

+0

Спасибо, но подумайте, что произойдет, если вы попытаетесь работать с базой данных, хранящейся на компакт-диске, вращающемся в 4-кратном медленном приводе с простым килобайтом буфера. Нет MMU, нет MMAP, нет оперативной памяти и нет реальной ОС. На самом деле 16 МБ ОЗУ на моей конкретной платформе, но я хочу использовать ее до краев. ;) Также я хочу почти полностью избежать накладных расходов на де-сериализации. Я был расплывчатым из-за особенностей устройства, потому что на самом деле хочу использовать части техники на нескольких игровых консолях, начиная с середины 90-х годов до нынешних карманных. Не обижайтесь, мне нравится SQLite, но это было бы самоубийством. – 3yE

4

На платформах, таких как Nintendo GameCube и DS, 3D модели, как правило, хранятся в очень простой пользовательский формат:

  • Краткий заголовок, содержащий магическое число, идентифицирующее файл, число вершин, нормалей, и т. д., а также контрольную сумму данных, следующих за заголовком (Adler-32, CRC-16 и т. д.).
  • Возможно сжатый список 32-битных 3-х точечных чисел с плавающей запятой для каждого вектора и обычного.
  • Возможно сжатый список ребер или граней.
  • Все данные находятся в исходном формате endian целевой платформы.
  • Формат сжатия часто тривиален (Хаффман), простой (арифметический) или стандартный (gzip). Все они требуют очень небольшой памяти или вычислительной мощности.

Вы можете использовать такие форматы как кий: это довольно компактное представление.

Мое предложение состоит в том, чтобы использовать формат, наиболее похожий на ваши структуры данных в памяти, чтобы свести к минимуму пост-обработку и копирование. Если это означает, что вы сами создаете формат, пусть будет так. У вас есть чрезвычайные потребности, поэтому необходимы крайние меры.

3

Отмечу, что нигде в вашем описании вы не просите «простоту программирования». :-)

Итак, вот что приходит на ум для меня, как способ создания этого:

  • Данные должны быть в том же формате на диске, как это было бы в памяти цели, так что он может просто вытащить капли из диска в память, не переформатируя его. В зависимости от того, какую свободу вы хотите вкладывать в память, «капли» могут быть целым файлом или могут быть меньшими битами внутри него; Я недостаточно понимаю ваши данные, чтобы предложить, как его подразделить, но, возможно, вы можете. Поскольку мы не можем полагаться на то же утверждение и согласование на хосте, вам нужно быть немного умным в переводе вещей при записи файлов на стороне хоста, но по крайней мере таким образом вам нужно только умение с одной стороны передачи, а не на обоих.

  • Для обеспечения некоторой уверенности в том, что код цели и стороны стороны соответствует, вы должны написать это в форме, где вы предоставляете единое описание данных и имеете некоторый код генерации, который будет генерировать как целевую -C-код и код Python на стороне хоста. Вы даже можете заставить генератор генерировать небольшой случайный номер «версии» в этом процессе и иметь код на стороне хоста, чтобы записать это в заголовок файла, а целевая сторона проверить его и дать вам ошибку, если они не совпадают , (Точка с использованием случайной величины является то, что только бит информации вы заботитесь о том, соответствуют ли они, и вы не хотите, чтобы увеличить его вручную.)

+0

Большое спасибо, это идет в правильном направлении. :) И, как было отмечено, гораздо легче, гибкость и надежность использования, чем «простота программирования» :) и производительность выше этого. Это будет огромный долгосрочный проект, и я не хочу в какой-то момент столкнуться с фиаско malloc, подразделение не будет идеальной гарантией, поэтому идея состоит в том, чтобы иметь отдельный большой и обычно загруженный объект куча, которую я могу сжать, возможно, даже сжимается, если нормальная куча заполнена. Тогда я думаю, необходимость в подразделении исчезает. Если у вас есть другие предложения, они были бы очень желанными. – 3yE