我目前正致力于跨平台应用程序,并对其他人如何解决以下问题感到好奇:
字节序
浮点支持(某些系统在软件中模拟,非常慢)
I/O系统(即显示,声音,文件访问,网络等)
当然,过多的编译器差异
显然,这是针对像c/c ++这样的语言,它们不会抽象大部分内容(不像java或c#,很多系统都不支持).
如果你很好奇,我正在开发的系统是Nintendo DS,Wii,PS3,XBox360和PC.
这是我解决问题的方式(如果你没有从上面的系统列表中猜到,我正在开发控制台/ Windows游戏).请记住,我工作的系统通常没有为他们编写的跨平台库(索尼实际上建议您从头开始编写自己的渲染引擎,并使用他们的OpenGL实现,这并不完全遵循无论如何,作为参考标准).
Endianess
我们的所有资产都可以为每个系统定制.我们所有的原始数据(纹理除外)都存储在XML中,我们在构建项目时将其转换为系统特定的二进制格式.看看我们如何开发游戏机,我们不需要担心在具有不同端格式的平台之间传输数据(只有PC允许用户这样做,因此,它也与其他系统隔离) .
浮点支持
大多数现代系统的浮点值都很好,例外的是Nintendo DS(和GBA,但这对我们来说几乎是一个死的平台).我们通过2个不同的类来处理它.第一个是"固定点"类(模板化,可以指定要使用的整数类型以及十进制值的多少位),它实现所有算术运算符(处理位移)并自动执行类型转换.第二个是"浮点"类,它基本上只是浮点数的一个包装器,大多数情况下,唯一的区别是它还实现了移位运算符.通过实现移位运算符,我们可以在DS上使用位移进行快速乘法/除法,然后无缝转换到更好地使用浮点数的平台(如XBox360).
I/O系统
这可能是我们最棘手的问题,因为每个系统都有有自己的控制器的输入,图形(XBOX360使用的DirectX9的变体,PS3有OpenGL,也可以从头开始编写自己和DS和Wii有方法thier自己的专有系统),声音和网络(真的只有DS的协议相差不大,但随后他们每个人都有,你必须使用自己的服务器系统).
我们最终解决,这是通过简单地写相当高的水平包装为每个系统的方式(如网格图形,用于控制器等关键绘图系统),并让所有的系统使用相同的头文件进行访问.这不只是一个写具体的cpp文件为每个平台(从而形成"发动机")的问题.
编译器差异
这是一件无法轻易解决的问题,因为我们遇到了编译器的问题,我们通常会在本地维基上记录信息(因此其他人可以查看要注意的内容以及使用它的变通方法)如果可能的话,写一个宏来处理我们的情况.虽然它不是最优雅的解决方案,它可以工作并看到某些编译器在某些地方被简单地破坏,但更优雅的解决方案往往会破坏编译器.(我只是希望所有编译器都实现了Microsoft的"#pragma once"命令,比在#ifdef中包装所有内容要容易得多)
很多这种复杂性通常由您使用的第三方库(boost是最着名的)解决.人们很少从头开始写一切......
对于从文件加载的数据中的endian问题,在文件头中嵌入一个值,如0x12345678.
加载数据的对象,查看此值,如果它与值的内部表示匹配,则该文件包含本机endian值.那里的负载很简单.
如果值不匹配,则它是外部字节序,因此加载器需要在存储它们之前翻转值.