我需要尽可能高效地在较旧的基于CD的游戏机上加载大型模型和其他结构化二进制数据。最好的方法是什么?数据将从Python应用程序导出。这是一个非常复杂的爱好项目。
Requierements:
我有一个半平面的解析Python琐碎,有限的语法C头,它将使用带偏移而不是指针的结构,以及主app中的便捷包装器结构/类,带有getter,可以将偏移转换为正确键入的指针/参考,但我想听听你的建议。
澄清:请求主要是关于数据加载框架和内存管理问题。
答案 0 :(得分:4)
在Nintendo GameCube和DS等平台上,3D模型通常以非常简单的自定义格式存储:
你可以把这样的格式作为一个提示:它是一个非常紧凑的表示。
我的建议是使用与您的内存数据结构最相似的格式,以尽量减少后处理和复制。如果这意味着你自己创建格式,那就这样吧。您有极端需求,因此需要采取极端措施。
答案 1 :(得分:3)
我注意到你的描述中没有任何地方要求“编程的简易性”。 : - )
因此,这就是我想到的一种创造方式:
数据应该与目标内存中的磁盘格式相同,这样它就可以简单地将blob从磁盘中拉入内存而无需重新格式化。根据您将内容放入内存所需的自由度,“blob”可以是整个文件,也可以是其中的较小位;我不太了解你的数据,不足以建议如何细分它,但可能你可以。因为我们不能在主机上依赖相同的字节顺序和对齐,所以在主机端编写文件时需要有点聪明才能翻译,但至少这样你只需要一方面的聪明才智转移而不是两者。
为了保证目标端和主机端代码匹配,您应该以提供单个数据描述的形式编写它,并使用一些生成代码来生成两者目标端C代码和来自它的主机端Python代码。您甚至可以让您的生成器在进程中生成一个小的随机“版本”号,并让主机端代码将其写入文件头,目标端检查它,如果它们不匹配则给出错误。 (使用随机值的关键是,您关心的唯一信息位是否匹配,并且您不希望手动增加它。)
答案 2 :(得分:3)
这是一种常见的游戏开发模式。
通常的做法是在离线预处理步骤中烹饪数据。生成的blob可以以最小的开销流入。 blob是平台相关的,应该包含正确的对齐和&目标平台的终结。
在运行时,您只需将指针强制转换为内存中的blob文件即可。您也可以处理嵌套结构。如果保留一个目录,其中包含blob中所有指针值的偏移量,则可以修复指针以指向正确的地址。这类似于dll加载的工作方式。
我一直在研究一个红宝石库,bbq,我用来为我的iphone游戏烹饪数据。
这是我用于blob标题的内存布局:
// 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
//
以下是我如何加载二进制blob文件并修复指针:
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库还没有为黄金时间做好准备,但是它可以为你提供一些如何在python中自己编写的想法。
祝你好运!
答案 3 :(得分:0)
考虑将数据作为BLOB存储在SQLite DB中。 SQLite非常便携,轻量级,ANSI C,同时具有C ++和Python接口。这将处理大文件,没有碎片,具有快速访问的可变长度记录,等等。其余的只是将结构序列化为这些BLOB。