经过6年的开发,今年秋天,
Haiku操作系统的第一个beta版本“ R1 / beta1”发布了。 我长期关注这个有趣的项目,该项目旨在重新创建和进一步开发1994-2000年间存在的
BeOS系统。 因此,当我在IT新闻站点上看到有关Haiku beta版发布的新闻时,我立即决定查看此期待已久的发行版中添加了哪些内容。 在将系统安装到
VirtualBox虚拟机中并对其基本功能有所了解之后,我认为对今天正在开发此操作系统的OpenSource社区有所帮助将是很好的。 我决定从获得的一些经验开始:移植一些游戏项目。
Haiku操作系统的桌面。后来,我尝试完善一些现有的应用程序和库。 这是我在本文将致力于的各种开放源代码存储库中的少量活动。 在其中,我将始终如一地描述遇到的问题,并讨论解决这些问题的方法。 我试图将在这项工作中制作的大多数补丁发送给
上游现有项目,以便为它们提供Haiku支持,并使他们的开发人员对替代操作系统的存在感兴趣。
Haiku操作系统使用
混合内核 ,该内核是微内核体系结构的实现,具有动态加载必要模块的能力。 它基于由前
Be Inc.工程师开发的
NewOS内核的分支
。 ,由Travis Geiselbrecht撰写。 今天,这位开发人员正在Google的
Zircon内核上开发新的
Google Fuchsia操作系统,但这是另一回事了。 因此,由于Haiku开发人员声明了与BeOS的二进制兼容性,因此他们被迫不支持两个熟悉的体系结构分支,而是支持三个:x86_64,x86和x86_gcc2。 后一种体系结构与旧版
GCC 2.95的编译器兼容。 多亏了她,可以运行为原始BeOS操作系统编写的应用程序。 不幸的是,由于兼容性问题,Haiku开发人员无法在系统API中使用C ++编程语言的现代功能。 但是,他们仅准备两种架构的安装映像:x86_64和x86。 事实是,x86的Haiku发行版是混合的:尽管事实上所有系统组件都是在x86_gcc2下构建的,以实现二进制兼容性,但仍为用户提供了安装或构建使用现代编译器和x86架构设计的任何现代应用程序的机会。 。 用于x86_64体系结构的Haiku发行版是完全64位的,不能运行32位BeOS和Haiku应用程序。 但是,API级别具有兼容性,因此,如果您在BeOS或Haiku x86下具有应用程序的源代码,则可以在Haiku x86_64下轻松地对其进行编译,并且一切正常。 如果您不需要任何特定的BeOS应用程序或32位Haiku应用程序的支持,则建议将x86_64体系结构的操作系统映像安装在实际硬件上。
值得一提的是,在此操作系统中,部分支持
POSIX标准。 该基础使其类似于UNIX系统,并且易于移植其软件。 主要的编程语言是C ++,由于Haiku的公共API主要追求面向对象的编程范例,因此正在积极使用。 但是,没有人禁止使用C编程语言,仅在大多数情况下才有必要编写相应的兼容性层。 操作系统的软件接口分为不同的系统框架,这些框架负责特定的机会,例如,提供接口或网络支持。 这有点像
macOS或
Qt框架中提供的功能。 必须指出的是,尽管可以为Haiku开发人员提供多用户工作模式方面的一些发展,但该操作系统是单用户操作系统。
我不得不与本文的读者分享使用Haiku中提供的高级应用程序窗口管理系统的积极经验。 在我看来,它是最方便的操作系统之一,并且以这种方式成为该操作系统的标志。
Haiku操作系统中的高级窗口管理:支持平铺和选项卡。可以像在现代浏览器中一样,将Windows固定在选项卡中,彼此连接并方便调整大小。
简单平铺 ,将某些应用程序的上下文从一个窗口转移到另一个窗口,并支持
复制 。 您可以在
官方文档中了解有关本地窗口系统的所有功能的更多信息,其中描述了所有必需的快捷键。
我不会在本文中完整介绍Haiku的所有功能,因为对此感兴趣的人将可以自己在Internet上轻松找到必要的信息。
内容:
1. Haiku中的软件包和存储库2.第一步:移植精金盔甲感情冒险3.修改现有的NXEngine端口(Cave Story)4.移植Gish游戏5. BeGameLauncher项目,该项目可让您快速创建游戏启动器6.移植Xash3D:传奇的半条命游戏和官方附加组件7.移植游戏《 Serious Sam》的两个部分:第一次遇到和第二次遇到8.移植Vangers游戏9. Haiku的SDL2库中对话框的实现10.移植我的Cool Reader叉子11. KeymapSwitcher程序的完成12.结论1. Haiku中的软件包和存储库
与原始的BeOS相比,Haiku出现了一项重大创新:软件包管理系统,其中包括用于从各种来源获取和安装软件的各种工具。 这样的资源可以是正式的
Haiku和
HaikuPorts信息库,非官方信息库,以及仅是单独准备的HPKG软件包。 这种用于安装和更新软件的功能在类Unix操作系统的世界中早已为人所知,但是现在,它们的所有功能和便利已成功达到Haiku,这不能不让该操作系统的普通用户满意。 得益于围绕软件包管理器构建的基础架构,现在任何开发人员都可以轻松地移植新的或修改现有的开源应用程序,然后将其工作结果添加到HaikuPorts软件端口存储库中,之后所有Haiku用户都可以使用它们。 结果,所产生的生态系统类似于具有
Homebrew的macOS操作系统,具有
端口的 FreeBSD,具有
MSYS2的 Windows或具有
AUR的 Arch Linux。
名为
HaikuPorter的构建软件包和移植软件的工具与操作系统分开提供,并使用GitHub信息库中的一本小
手册进行安装。 从同一个GitHub安装此实用程序后,将下载整个配方树,开发人员正在使用它。 该食谱是一个常规的Shell脚本,其中包含HaikuPorter将收集所需的HPKG软件包的说明。 值得注意的是,该工具本身是用
Python 2编程
语言编写的,与现有的软件包管理系统紧密交互,并在内部使用标准工具
Git来修复对软件源代码的更改并生成一组补丁。 由于有了这种技术堆栈,以补丁集文件的形式制作用于构建HPKG软件包和软件补丁的方法非常方便和简单。 在大多数情况下,使用HaikuPorter时,我仅需使用三个命令:
alias hp="haikuporter -S -j4 --get-dependencies --no-source-packages" hp libsdl2 hp libsdl2 -c hp libsdl2 -e
第一个命令只是收集选定的软件包,第二个命令清除构建目录,第三个命令根据您通过提交记录在工作目录的Git存储库中的更改来创建或更新一组补丁程序。
因此,为了将程序包发布到HaikuPorts存储库并使其对所有Haiku用户可用,开发人员必须安装HaikuPorter,展开配方树,在本地收集HPKG程序包并对其进行测试,然后提交到其配方树的分支。然后在GitHub上发出
Pull请求 。 Haiku开发人员应考虑已发布的工作,然后决定将您的更改合并到存储库中或将其发送以进行修订。 如果更改被接受,则安装在构建服务器上的相同HaikuPorter将远程收集软件包并将其自动发布到存储库。
Haiku操作系统的“ R1 / beta1”的beta版中添加了一个特殊的
HaikuDepot程序,该程序允许通过图形用户界面(而不是通过终端中的控制台命令)使用软件包和存储库。
在Haiku操作系统上运行的HaikuDepot程序。借助此工具,经验不足和新手的Haiku用户都可以方便地管理其软件包库。 值得注意的是,该应用程序不仅是现有程序包管理器上的GUI外壳,而且还实现了其他功能。 例如,授权用户可以对可用于安装的软件包进行评分并撰写评论。 另外,HaikuDepot有一个特殊的
Haiku Depot网站,它使您可以在Internet上查看软件包更改或下载单个HPKG软件包。
<<跳到内容2.第一步:移植精金盔甲感情冒险
在熟悉VirtualBox虚拟机中的操作系统功能之后,我决定评估其中的SDL2库,并将
Adamant Armor Affection Adventure游戏移植到Haiku,我之前写过有关转移到Android平台的文章。 构建程序不需要对源代码进行任何更改,我只是从存储库中安装了所有必需的工具,库及其头文件,并执行以下操作:
cmake -DCMAKE_BUILD_TYPE=Release -DGLES=off -DANDROID=off -DCMAKE_C_FLAGS="-D__linux__" -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake --build .
=关-DCMAKE_C_FLAGS = “ - D__linux__” -DSDL2_INCLUDE_DIR =`finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR =`finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake -DCMAKE_BUILD_TYPE=Release -DGLES=off -DANDROID=off -DCMAKE_C_FLAGS="-D__linux__" -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` -DSDL2_MIXER_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` ../aaaa/src/main/cpp cmake --build .
由于Haiku具有POSIX,因此-D__linux__或
-D__unix__定义解决了许多与定义平台相关的问题。 但是,值得注意的是,如果存在类似的构建问题,则最好放弃使用它们并在项目源代码中实现Haiku支持。 通过使用特定参数调用
finddir系统实用程序,可以为各种体系结构获取正确的头文件路径。
因此,通过执行上述命令,我编译了一个可以完美运行的可执行文件,并且游戏运行完美。 我认为用游戏准备一个自给自足的HPKG软件包会很酷,为此,我深入互联网以寻找所需的信息。 然后,我不知道有什么便捷的软件移植工具,例如我在上一节中写的HaikuPorter,因此为了实现我的目标,我决定作弊并反汇编一些系统软件包,以了解其内部和内部的排列方式。打个比方。
在Internet上,我找到了所需的
信息 ,然后使用内置在本地文件管理器中的
Expander存档器解压缩了一个随机系统软件包,找到了
.PackageInfo文件,对其进行了编辑,然后根据我的应用程序的结构替换了这些文件。 然后,我只运行了命令以构建HPKG软件包并将其安装在系统上:
package create -C AAAA/ aaaa.pkg pkgman install aaaa.pkg
不幸的是,无法从“应用程序”菜单启动游戏。 通过在终端中运行可执行文件,我收到一条错误消息,指出无法找到运行和运行应用程序所需的数据文件。 在这种情况下,如果在终端中转到应用程序包的目录,则一切正常。 这使我想到,从菜单启动游戏时,您需要强制更改应用程序目录。 这可以使用Shell脚本或更改游戏源来完成。 我选择了第二个选项,并添加了类似于以下代码的内容:
#ifdef __HAIKU__
在start函数
main()的最开始,它完全解决了这个问题,并且该包证明是可行的。 在有关
Linux.org.ru上Haiku beta版发布的新闻的评论中
,我删除了组装好的程序包的链接,并要求某人将我发送到该操作系统的一些活跃用户社区,然后上床睡觉。
在Haiku上运行的Adamant Armor Affection Adventure游戏端口。早晨,一个使用
3dEyes昵称的人给我写了一封电子邮件。 后来
发现 ,活跃的Haiku开发人员之一,该操作系统的Qt框架端口的作者
Gerasim Troeglazov躲在这个名字后面。 他向我展示了HaikuPorts存储库,并告诉我如何使用HaikuPorter实用程序。 此外,他写了一个为Adamant Armor Affection Adventure构建HPKG软件包的方法,并将其添加到HaikuDepot中。
在分析了该开发人员所做的所有更改之后,我注意到手动组装的软件包中存在一些缺陷,例如,由于已安装软件包的安装目录不具有写功能,因此未保存设置。 借助特殊目录中的符号链接可以很好地解决写入设置或保存在他的包中的问题,该目录可访问以进行记录并用于保存用户数据。 我的包裹也没有自己的原始图标。
此外,我了解到Haiku没有3D图形的硬件加速,并且使用CPU功能以编程方式渲染了相同的OpenGL。 对于重型图形应用程序,这当然是不好的,但是对于较旧的游戏,这绰绰有余。 我什至决定专门检查游戏程序包,并将Haiku安装在我的旧笔记本电脑上,也就是实际硬件上。 令我惊讶的是,Adamant Armor Affection Adventure图片的渲染速度如此之快,以至于如果他们没有告诉我缺少硬件加速的信息,我将不会注意到该渲染是由处理器完成的。
项目来源: https : //github.com/EXL/AdamantArmorAffectionAdventure我推迟了手动创建HPKG程序包的过程,直到更好的时机,然后完全切换为使用HaikuPorter工具并编写配方。 但是有时在某些情况下需要手动重建软件包。 例如,如果HaikuPorter在
.PackageInfo文件中将Haiku夜间版本设置得太高,则需要在操作系统的发行版上测试该软件包。 值得注意的是,由于有了Gerasim的响应能力和丰富的经验,我才能够了解为Haiku操作系统创建软件包的许多微妙之处,并进一步进行了我的工作。
<<跳到内容3.修改现有的NXEngine端口(Cave Story)
在HaikuPorts存储库中找到一个配方,引用了我的
NXEngine引擎前叉,使我感到非常惊讶
,该游戏在我的
博客上已经
进行了很长时间的
分析了 。 食谱和补丁由名为
ZoltánMizsei的开发人员使用昵称
extrowerk和Haiku的许多软件包的积极维护者准备的。
进行了表面分析,安装了软件包并启动了应用程序,发现了与我在本文上一节中描述的问题相同的问题:游戏的保存不起作用,设置也没有保存,并且软件包没有原始图标。 我决定修复这些缺陷,并开始研究补丁,首先整合所有extrowerk的想法。 我为Haiku操作系统编写了原始的
Makefile ,并更正了写入和保存各种用户数据的过程。
在Haiku操作系统中启动的基于NXEngine引擎的Cave Story游戏端口。由于游戏假定俄语和英语版本具有一组不同的可执行文件和数据文件,因此我决定制作一个通用软件包,该软件包将两个版本同时组合在一起,并根据用户选择的系统语言自动选择正确的版本。 这是通过最简单的Shell脚本实现的:
在“应用程序”菜单中选择一个游戏项目时,将启动此脚本,并确定当前的系统区域设置。 如果用户选择俄语作为系统语言,则将启动游戏的俄语版本,在所有其他情况下,将启动英语版本。
但是,随着应用程序原始图标的创建,我不得不进行一些修改。 事实是,在Haiku操作系统中,仅
允许使用特殊
HVIF格式的矢量图标,这些图标被设置为
Be File System文件系统的属性。 在官方文档中,有两本用于创建自己的应用程序图标的大型手册:
第一本手册介绍了图形和设计的样式,
第二本手册详细介绍了如何使用
Icon-O-Matic系统程序来创建图标。
Icon-O-Matic允许您导入最简单的SVG文件,并将生成的图标导出为HaikuPorter必需的格式,称为HVIF RDef,表示相同的HVIF,但转换为文本视图。 RDef文件不仅可以包含图像,还可以包含其他信息,例如,应用程序的版本及其描述。 在某些方面,这些文件类似于Windows中使用的RES文件。 配方中的以下命令将编译RDef文件,并将结果设置为特殊属性:
rc nxengine-launcher.rdef resattr -o "$appsDir/NXEngine/Cave Story" nxengine-launcher.rsrc addResourcesToBinaries $sourceDir/build/nxengine-rus.rdef "$appsDir/NXEngine/RUS/Cave Story"
另外,在配方中定义了函数
addResourcesToBinaries ,该函数可自动完成这项工作。 Icon-O-Matic有一个但非常严重的问题:流行的
Inkscape矢量编辑器保存的SVG文件无法打开,或者在不支持某些必要功能(例如渐变)的情况下导入。 因此,通过使用各种付费和免费的在线和离线转换器将光栅图像转换为矢量图像,然后在Icon-O-Matic中打开生成的SVG文件的冒险任务,我惨遭失败。 后来,我解决了打开SVG文件的问题,找到了一种解决方法,但是我将在下面对此进行介绍。 同时,我决定利用Icon-O-Matic的标准功能并自己绘制图标。 经过半个小时的像素硬拷贝,我得到了以下图像:
Haiku操作系统中的标准Icon-O-Matic程序。是的,我使用矢量编辑器创建了像素艺术类型的图像。 以我业余的观点来看,一个不精通艺术的男人,结果很好。 我以所需的格式保存了此图标,准备了所有更改,更新了配方并将所有内容发送到HaikuPorts存储库。
项目源代码: https : //github.com/EXL/NXEngine为了
防万一,我将结果软件包发送给了
Cave Cave(Doukutsu Monogatari)游戏的粉丝网站,该游戏的管理部门在下载部分添加了Haiku操作系统。
<<跳到内容4.移植Gish游戏
我决定转移到Haiku的下一个项目是
Gish游戏,我之前已将其移植到Android。 HaikuPorts存储库中有一个未完成的免费游戏
Freegish的实现
方法 ,所以我决定也在那里添加原始游戏,但是没有数据文件,因为它们与引擎不同,它们是单独提供的,而且不是完全免费的。
在Haiku操作系统上运行的Gish游戏端口。移植此游戏没有任何特殊问题。 执行以下构建命令后立即编译可执行文件:
cmake gish/src/main/cpp/ \ -DGLES=0 \ -DANDROID=0 \ -DSDL2_INCLUDE_DIR=`finddir B_SYSTEM_HEADERS_DIRECTORY` \ -DCMAKE_C_FLAGS="`sdl2-config --cflags` -D__linux__" \ -DCMAKE_BUILD_TYPE=Release cmake --build .
接下来,我实现了从“应用程序”菜单启动游戏的功能,并提供了将用户数据保存到可访问的目录的支持,该目录可用于记录并用于此目的:
char* getHaikuSettingsPath() { char path[PATH_MAX]; find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, path, sizeof(path)); strcat(path, "/Gish/"); return strdup(path); }
使用Haiku API的
find_directory()函数的
getHaikuSettingsPath()函数形成了我所需目录的完整路径。
项目源代码: https : //github.com/EXL/Gish仍然需要解决以下问题:用户应如何选择包含Gish游戏原始文件的目录? 您可以尝试使用Shell脚本和
警报系统实用程序解决问题,但我决定更彻底地解决此问题,并使用Haiku API和
Interface Kit框架实现方便的GUI启动器。
<<跳到内容5. BeGameLauncher项目,该项目可让您快速创建游戏启动器
决定使用1998年旧标准的C ++编写我的BeGameLauncher项目,使用操作系统的本机工具创建带有图形用户界面的应用程序。 由于Haiku和BeOS的许多程序的名称都以“ Be”前缀开头,因此我也决定为该项目选择这样的名称。 我决定首先熟悉接口套件框架,该框架是Haiku API的一部分。 除了Haiku官方网站上相当详细的文档之外,我还找到了两个非常出色的
DarkWyrm课程 ,这些
课程使新手开发人员可以快速了解某些系统类的工作方式。 第一门课程称为
“使用Haiku编程学习”,一开始介绍C ++编程语言的基础知识,对初学者非常有用。 第二门课程称为“
用Haiku编程” ,适用于已经熟悉C ++并具有该语言基础知识的人员。 这两门课程都讨论了Haiku API的最多样化方面,因此对于希望开始为此操作系统创建应用程序的任何人都将非常有用。
在对角阅读了这份出色的材料之后,我对Haiku API有了一个总体印象,并开始考虑下一步。 我已经有一些使用Qt框架开发应用程序应用程序的经验,该框架也是用C ++编程语言编写的,并且使用了面向对象的编程范例。 因此,除了缺少信号系统和插槽之外,Haiku API与它非常相似,因此我经常会与Qt进行一些比较。 此外,值得注意的是,使用了Haiku API中常见的
事件驱动的编程原理,该原理允许各种实体通过事件或消息的传输相互进行交互。 这里的
QEvent类的类似物是
BMessage类,围绕该类构建对象的交互系统。
BMessage类的实例通常会获得一个唯一的编号,该编号使您可以在常见事件过滤器中标识发件人及其操作。
对于我的项目,我必须选择适当的Haiku API类,以使我能够实现预期的功能。 首先,要启动外部应用程序,必须找到
QProcess类或
execve() POSIX函数的类似物,顺便说一句,它在Haiku操作系统中也能正常工作,但是,我决定使用本机工具会更好,但以防万一这种情况留下了通过POSIX功能启动应用程序的可能性。 进程间通信类
BRoster对此非常
有用 。 它找到了合适的
Launch()方法,该方法允许您指定可执行文件的路径并将参数传递给该文件。 由于启动程序应该能够保存一些参数,例如,用户选择的包含游戏数据文件的目录,因此我需要一个可以完成所有这些操作的类。 在Qt中,此类称为
QSettings ,在Haiku API中,正如Gerasim提示我的那样,有一个我已经
知道的
BMessage类,它具有非常有用的功能。 问题是此类信息可以轻松地序列化,例如保存到磁盘。 这非常方便,通常用于在程序中记录任何用户数据,这就是为什么我选择此类将设置保存在项目中以实现启动程序的原因。
不幸的是,Haiku API找不到QDebug类的类似物,因此我只是在开发过程中使用标准C编程语言的fprintf()函数将调试输出发送给了stderr:
我将此函数包装在对我来说方便的BeDebug()实体中,该实体取决于所选的语言标准是宏还是函数。这样做是由于C ++ 98不支持带有可变数量参数的宏。Qt框架还有一个有用的QMessageBox类,通过它可以创建一个模式对话框,其中包含用户应注意的任何信息,例如错误或警告。 Haiku API为此具有一个BAlert类。其实现与Qt中的实现有所不同。例如,此类的对象必须在堆上而不是堆栈上创建,因为在执行某些用户操作后,它必须删除自身。至于图形界面的其他类别,在这里我绝对没有遇到任何困难,并且发现了我所需的一切而没有任何问题。现在,我应该考虑一下该项目的简单体系结构。我决定集中精力创建一个静态库,在该库中将设计两个类来继承它们自己的派生类。第一个也是最重要的类,BeLauncherBase,负责创建主启动器窗口,传输所有用户参数,并提供添加自己的GUI元素的功能。第二个类BeAboutWindow只是负责打开“关于程序...”对话框,并在单独的窗口中显示信息。因此,程序员需要执行两个简单的步骤来创建他的启动器,例如,玩Gish: class GishAboutWindow : public BeAboutWindow { ... }; class GishLauncher : public BeLauncherBase { ... }; int main(void) { BeApp *beApp = new BeApp(SIGNATURE); GishLauncher *gishLauncher = new GishLauncher(BeUtils::GetPathToHomeDir()); beApp->SetMainWindow(gishLauncher); beApp->Run(); delete beApp; beApp = NULL; return 0; }
首先,创建一个适当的启动函数main(),其次,简单地从上面的两个类继承并在其中实现必要的方法。之后,我们使用链接到我的静态库的工具编译生成的C ++文件,然后准备好Gish游戏的启动器。游戏Gish端口的启动器中的“关于程序...”对话框。接下来,我考虑了如何将参数从启动器传输到引擎本身或游戏的可执行文件。我只看到两种解决此问题的方法。第一种方法是更改环境变量。实际上,在单击“运行”按钮后,启动程序只需调用setenv()函数即可将所有参数放入环境变量中,然后游戏引擎使用getenv()函数读取这些参数,这看起来非常简单。此处可能出现的唯一问题是BRoster类及其Launch()方法:我不知道借助此类启动的应用程序是否会继承在启动程序中设置的所有那些环境变量。经过一些实验,环境变量的继承得到确认,我在项目中完全实现了此方法。解决该问题的第二种方法是设置特殊的命令行参数。实际上,启动器只需将所有设置放在适当的参数中,并使用它们调用应用程序可执行文件。但是游戏引擎已经必须独立处理它们,这带来了一些困难。例如,如果游戏不具备通过命令行参数指定游戏文件路径的可能性,则有必要在引擎本身中修改参数解析器。尽管有这些问题,我实现了这种互动方式,因此我得到了一个很好的机会,将所有内容结合在一起。这使我可以创建一个字符串,用于在某些启动器中指定用户参数。设计完所有组件后,我决定为我的项目选择一个组装系统。仅考虑了两个选项:“类固醇上”的Makefile和CMake。在第一种情况下,Haiku操作系统的开发人员准备了一个方便的makefile-engine程序包,其中他们收集了开发人员通过开始在Haiku API上编写应用程序所面临的所有必要功能,例如自动翻译生成和应用程序资源的编译。但是我不是那些寻求简单方法的人,因此我选择了CMake并将部分工作从makefile-engine软件包转移到了其中。结果,您可以在项目存储库中查看生成的可怕的汇编脚本,下面将链接至该链接。Haiku的Gish游戏端口启动器的屏幕截图。我想就应用程序本地化写几句话。在Qt框架,因为这有一个方便的包装函数TR() ,两个辅助工具lrelease,即可和lupdate,从事翻译文件的产生。该框架甚至包括一个特殊的Qt语言学家程序,该程序具有为翻译人员设计的便捷图形用户界面。在Haiku API中,应用程序本地化工具使用起来不太方便,而且比较陈旧。建议将需要翻译的行包装在特殊宏B_TRANSLATE()中,并将定义B_TRANSLATION_CONTEXT添加到源文件中,将一组可翻译的字符串与另一组分开。之后,需要完成一个非常奇怪的事情:在绝对所有项目源文件上使用-DB_COLLECTING_CATKEYS标志设置编译器预处理器,使用grep实用工具做一些魔术,最后得到一个巨大的PRE文件。collectcatkeys实用程序将与此文件一起使用,该实用程序将已经创建了易于阅读且易于编辑的转换器CATKEYS文件。本地化字符串后,您需要使用linkcatkeys实用程序,这会将翻译添加到可执行文件的资源中。因此,当选择特定的系统语言时,应用程序将显示翻译后的行。奇怪的是,有关应用程序本地化的Haiku API文档包含的信息很少。但是,在官方站点上,我找到了一篇很棒的文章“ 本地化应用程序”,其中详细介绍了此操作系统的应用程序翻译的许多方面。据我了解,原始的BeOS没有Locale Kit框架,仅被添加到Haiku中。我的下一步是选择一种环境,以使用C ++编程语言开发应用程序。由于这样的事实,俳句已经被移植到Qt框架中,库提供此类HaikuPorts的IDE,比如Qt Creator中和开发。此外,还有一个JVM端口,该端口允许您使用以Java编程语言编写的IDE,例如NetBeans或IntelliJ IDEA。我选择Qt Creator开发环境,尤其是因为在其最新版本中,使用LibClang解析器对代码进行了高质量的分析,它比标准解析器更准确,更快捷地工作。在Haiku操作系统上运行的集成开发环境Qt Creator。就Haiku中著名的跨平台IDE而言,一切都很好。但是排他性解决方案呢?我不得不提到一个非常有趣的项目,该项目由DarkWyrm赞助,并且目前支持Adam Fowler,它被称为Paladin。该程序使Pe文本编辑器几乎可以在操作系统发行版中使用,成为真正的IDE。从HaikuPorts系统信息库安装的Haiku Paladin IDE。使用Haiku窗口系统中集成的平铺,您可以将Paladin窗口连接到Pe编辑器的侧面并添加一个终端。在HaikuPorts存储库中,还有一个方便的Koder文本编辑器,它类似于流行的Windows 记事本++程序,并且也基于Scintilla项目的经验。对于我的应用程序,我创建了一个项目PLD文件,现在任何使用Paladin IDE的开发人员都可以在此程序中轻松打开我的项目。设置好Qt Creator开发环境并准备就绪后,我便开始意识到所有计划中的功能。我遇到的第一个问题与更改系统字体大小时缩放控件有关。最初,在BeOS中,所有GUI元素放置代码都是在坐标中显式设置的。这非常不方便,冗长,并且产生了很多问题,例如,使用相同的字体大小更改,整个应用程序形式便分散了,变得无法使用。幸运的是,Haiku试图解决此问题,并添加了Layout API,它是Interface Kit框架的一部分。通过使用布局API,启动器可以正确响应Haiku中系统字体的大小更改。这项创新完全解决了我的定位控件问题,并且我使用Layout API重新编写了应用程序,从而严重缩短了某些地方的代码长度。在Haiku官方网站上,我发现了一系列有趣的“ 全部铺设”文章,这些文章证明了创建此软件界面的原因并显示了其用法示例。当Gerasim尝试使用我的库为他移植的游戏创建启动器时,发现了另一个问题。问题是我经常使用Haiku操作系统本身的源代码来实现各种功能。尤其是,我找到了一个在其中的BRoster类对象上使用Launch()方法的示例。问题表现为以下事实:该示例不正确,并且Gerasim移植的游戏引擎无法正确解析启动程序设置的参数。对Haiku源代码进行了更深入的研究后,我发现对于Launch()方法,不需要显式设置第一个参数,该参数应包含可执行文件的完整路径,因为它将自动设置。
Launch()方法的文档没有说不需要第一个参数,这可能是开发人员错误地编写此代码的原因。我在项目中修复了此错误,并单独解决了Gerasim问题。但是Haiku操作系统本身的这个小错误怎么办?我决定也要修复她。幸运的是,事实证明这很容易做到!您需要使用GitHub登录到Haiku Code Review Gerrit资源,添加您的公共SSH密钥,派生Haiku源代码,创建一个commit提交,并将生成的补丁发送到Code review给特权开发人员: git clone ssh://EXL@git.haiku-os.org/haiku --depth=1 -b master && cd haiku git commit git push origin master:refs/for/master
如果您需要更新已经发送的补丁,那么在发送更改或新提交之前,请确保在提交消息的末尾添加Haiku Code Review服务提供给我们的ID。发送补丁后,Haiku开发人员必须批准,拒绝或将其提交以进行修订。以我为例,更正立即被接受,并且这个小缺陷现在已在所有地方得到修复。如果需要在将修补程序发送到存储库之前对其进行测试,则可以尝试使用jam实用程序来编译单独的应用程序,该程序是Perforce Jam构建系统的分支,用于构建Haiku操作系统的整个代码库。源代码存储库具有文件ReadMe.Compiling.md,这将帮助您处理所有编译技巧。在完成项目时,我发现了Icon-O-Matic程序无法打开使用Inkscape矢量编辑器创建的SVG文件的原因。问题是Icon-O-Matic无法处理viewBox属性,但是,如果您找到一个没有此属性的简单SVG文件,请使用Inkscape对其进行编辑并将其另存为Plain SVG文件,它将在Icon-O中打开-Matic。因此,我将这样准备好的SVG文件放入存储库中,该文件可以进行编辑,并且可以在Icon-O-Matic中打开而没有任何问题。此外,我在项目的自述文件中添加了一条有关如何使用Inkscape为启动器创建图标的小指令。我决定使用各种静态分析器检查项目代码,但他们没有发现任何严重的问题。但是后来我发现了一个他们无法检测到的问题。该静态方法事实上GetBitmap()类BTranslationUtils可以返回NULL:
在Draw()方法中,我无意间忘记了检查fBitmap类的字段的有效性。因此,如果找不到某个图片,该应用程序可能会崩溃,但根据计划,它会绘制一个红色正方形。我告诉这个故事的事实是,静态分析器远非万能药,在任何情况下都需要使用C ++编程语言编写代码时要专心。BeGameLauncher项目的源代码和我所有的最佳实践均已上传到GitHub上的存储库。我希望该程序对某人有用,并且可以作为Haiku的简单应用程序的某种教程:该项目的源代码:https : //github.com/EXL/BeGameLauncher对于那些将在我的HaikuPorts存储库食谱中使用我的启动器的人的一些建议。如果要从某些程序读取的Haiku应用程序列表中隐藏游戏可执行文件,而只在其中保留启动器,则可以使用以下技巧: settype -t application/x-vnd.Be-elfexecutable $appsDir/Gish/engine/Gish rc $portDir/additional-files/gish.rdef -o gish.rsrc resattr -o $appsDir/Gish/engine/Gish gish.rsrc
这将排除在没有启动程序从各种程序(例如QuickLaunch)传递参数的情况下运行可执行文件的能力,这些程序用于快速启动应用程序。在这种情况下,可执行文件上的原始图标将被保存。<<跳到内容6.移植Xash3D:传奇的半条命游戏和官方附加组件
Xash3D项目是GoldSrc引擎的免费实现,该引擎在游戏Half-Life和其官方附加组件中使用。 Xash3D开发的背后是国内程序员Unsha Misha,他仍然协调其开发和改进。不久之后,其他开发人员加入了该项目,创建了FWGS Xash3D分支,并支持大量非Windows操作系统。今天,FWGS Xash3D项目的主要程序员是mittorn和a1batross(libpony),最后一个人是曾经很受欢迎的MotoFan.Ru论坛的积极参与者。我仍然在业余时间管理。我想知道:为什么不将此引擎移植到Haiku,为Xash3D项目增加对如此有趣的操作系统的支持,并为Haiku用户提供玩传奇游戏Half-Life的机会?此事仍然很小-必须立即开始移植工作,如果成功,则要发布这项工作的结果。在花了几个小时研究了项目结构和负责支持各种平台的代码部分之后,我开始对Xash3D引擎进行更改以提供对Haiku操作系统的支持。用老式的方式,我定义了编译器-D__linux__并尝试构建可执行文件和一堆库。出乎意料的是,事情进展得很快,到了晚上,转发了游戏的数据文件后,我设法启动了《半条命》,然后坐火车去了黑梅萨的主要车站。在Qt Creator IDE中将Xash3D引擎移植到Haiku的过程。由于该项目使用跨平台SDL2库这一事实,因此大大简化了引擎的移植,因为您无需编写任何依赖平台的代码,例如:输出声音,使用OpenGL上下文创建窗口或处理输入事件。所有这些已经在SDL2库中实现,并且可以使用。网络支持出现了一个小问题,因为Haiku有一个单独的库来实现网络堆栈,因此需要将其链接到引擎。我写了一些更高的关于创建启动器的项目,对我来说非常有用。利用C ++类的继承,我认真地扩展了其功能,并实现了选择游戏中各种附加功能的能力:Haiku的Xash3D引擎端口启动器的屏幕快照。想法是这样的:定义三个环境变量,使您可以灵活地配置游戏引擎以启动特定的加载项。在这种情况下,让用户使用可执行文件的各种参数进行播放,而当引擎仅位于具有所需数据文件的目录中时,就可以便携式启动引擎,这将是很有用的。因此,第一个环境变量XASH3D_BASEDIR负责用户从启动器中选择的带有游戏文件的目录。第二个变量XASH3D_GAME负责用户选择在启动器中启动的附加功能。这是第三个变量XASH3D_MIRRORDIR,仅对高级用户有用。它允许您将Xash3D系统目录镜像到用户的任何可写磁盘空间。因此,想要在Haiku下的Xash3D引擎上发布他的附加游戏的人只需要从他的项目的源代码中收集几个针对不同体系结构的动态库:•./cl_dlls/libclient-haiku.so•./dlls/libserver-haiku .so•./cl_dlls/libclient-haiku64.so•./dlls/libserver-haiku64.so然后将它们放在附加组件的相应目录中。对于我的Xash3D端口,我决定为“半条命”游戏预编译流行的加载项库,即Blue Shift和Opposed Force,它使用户可以简单地下载其数据文件,选择目录并启动游戏,而无需进行任何库编译。在移植Xash3D引擎的过程中,我遇到了一些有趣的问题。事实证明,要确定传递--help参数时生成的可执行文件的参数的帮助消息的长度,引擎将使用MAX_SYSPATH常量的预定义大小,该常量是另一个MAX_PATH常量的别名,该常量的值已从Haiku API中获取。因此,很长一段时间以来,我都不明白为什么该证书发行不完整,并且在最有趣的地方被切断。起初,我以某种奇怪的方式对标准错误输出流犯了罪stderr连接了缓冲,甚至试图强行禁用它。一段时间后,我想起了Haiku操作系统中MAX_PATH常量非常小的大小,这让我感到惊讶。该常数假定路径大小仅为1024字节。当我将消息大小增加到标准4096字节后,我的猜测就完全得到了解决,问题得以解决。从这个有趣的故事中可以得出以下结论:不应在与文件路径无关的字符数组中使用MAX_PATH常量。在Haiku操作系统中使用Xash3D引擎发布了游戏Half-Life以及其官方新增的Blue Shift和Opposed Force的屏幕截图的拼贴(预览,参考增加)。另一个问题是使用引擎本身的功能来选择游戏的附件时发生崩溃。事实证明,设置 XASH_INTERNAL_GAMELIBS定义时,客户端库加载的次数不是一次,而是两次。这就带来了类似的问题。正如a1batross向我解释的那样,这样做是为了可以将OpenVGUI库静态链接到客户端库。在Haiku的Xash3D端口中,该库没有任何使用方式,因此我避免使用默认库XASH_INTERNAL_GAMELIBS,并将此错误报告给引擎的开发人员。然后,当我单击在Xash3D中运行的游戏中的链接时,我发现无法打开Haiku内置的WebPositive浏览器。这个问题真的很奇怪,因为当从终端启动引擎时,浏览器会打开,但是当使用启动器启动引擎时,他拒绝这样做。在研究了一些代码之后,我找到了调用execve(),尝试将其替换为system(),此后浏览器开始打开而没有任何问题。发生错误时,Xash3D引擎会主动使用SDL_ShowSimpleMessageBox()和SDL_ShowMessageBox()函数调用,只有Haiku的当前SDL2库端口不支持创建这些对话框。我们的库版本根本不具备此功能。但我将在下面讨论解决此问题。Xash3D引擎的端口,已发布到Haiku Depot存储库。还值得注意的是,在将Xash3D引擎转移到Haiku之前,Gerasim Troeglazov在SDL2中实现了鼠标光标捕获。在此之前,玩3D游戏几乎是不可能的。过了一会儿,他修复了一个棘手的错误,即玩家在太空中的移动逐渐变慢,游戏开始急剧减速。事实证明,默认情况下会发送鼠标光标事件及其在屏幕上的所有移动历史。因此,这个故事在游戏过程中迅速膨胀,一切开始大大放缓。在Haiku SDL2端口中禁用此功能可以解决此问题,现在您可以玩半条命了,没有任何问题。虽然,在较弱的硬件上缺少3D加速使人感到自己。并且,如果游戏在窗口中正常运行并且完全不减速,则在全屏模式下FPS会大大降低。但是在这里,这只会帮助至少在流行的英特尔处理器中内置的那些GPU的视频驱动程序中添加硬件加速。项目源代码:https : //github.com/FWGS/xash3d我已将对源代码的所有更改发送给FWGS Xash3D项目的开发人员,他们在存储库中接受了这些更改,并且此引擎的软件包已在HaikuPorts和HaikuDepot程序中长期提供给任何Haiku用户。 。<<跳到内容7.移植游戏《 Serious Sam》的两个部分:第一次遇到和第二次遇到
最近,来自Croteam的开发人员发布了“ 严重引擎”的源代码,该引擎已在“严重萨姆”系列的游戏中使用:“第一次遇到”和“第二次遇到”。我决定将其移植到Haiku操作系统,下载源代码并开始工作。Haiku的“严重引擎”端口启动程序的屏幕快照。更改后的可执行文件的汇编工作没有任何问题,但是由于错误注入了SDL2对话框,因此启动游戏并不容易,该库的版本中没有针对Haiku的实现。因此,我不得不拿起经过时间考验的标准错误输出流stderr,并慢慢地解决问题,结果主要是因为缺少所需的游戏数据文件。严重萨姆(Serious Sam)的屏幕截图:使用Haiku操作系统的严重引擎端口启动了Second Encounter游戏。将下载的文件分解到所需的目录后,我可以毫无问题地运行此精彩游戏的第二部分,甚至可以穿越美丽的丛林。尽管缺少3D加速,但是如果您在窗口(而不是全屏)模式下运行游戏,处理器会绘制游戏的图形效果。当然,该引擎的FPS比我上面写过的Xash3D引擎低得多,但是这里的图形更现代,更好。经过少量操作后,我们设法启动了游戏的第一部分,这需要一个不同的可执行文件和一组不同的动态库。出乎意料的是,她的收入要快一些,显然其中的图形要求不是很高。在研究引擎设置时,我发现了大量图形参数可以显着减少处理器的负载,对于Haiku来说,这非常有用。“ Serious Sam:第一次遭遇”游戏的屏幕截图是使用Haiku操作系统的“严重引擎”端口启动的。我决定一次为游戏的两个部分制作一个程序包,只需选择一个包含适当数据文件集的目录,即可在它们之间进行切换。例如,如果启动器中的用户选择了包含《游戏:严重的山姆:第一次遭遇》文件的目录,则将启动相应的可执行文件,并加载相应的动态库集。并且,如果他选择包含“严重山姆:第二次遭遇”游戏文件的目录,则启动程序将相应地启动另一个可执行文件,该文件将加载其自己的共享库集。不幸的是,这并非没有问题。游戏中视频模式分辨率的反复变化导致整个引擎崩溃。在这种情况下,在我的Linux发行版中,没有崩溃。我花了很多时间来定位和修复问题。原来,要点是,随着分辨率的每次更改,SDL_Window窗口都被破坏并再次创建同时,OpenGL渲染器无法及时切换,并试图在损坏的窗口中绘制一些东西。 Haiku上的SDL2库端口的此类技巧无法阻止。解决该问题的所有简单尝试都无济于事,我不得不认真地研究逻辑并更改行为,以使在更改分辨率时窗口不会中断,但其参数只是更改了。这有助于消除崩溃,但增加了其他限制:现在,要激活全屏模式,您需要重新启动引擎。另一个问题是游戏中缺少音乐。但是,在Linux上,同样没有发生此问题。检查引擎的源代码后,我发现播放音乐取决于libvorbisfile库,但是引擎本身不与其链接,而是使用dlopen()系统功能将OGG音频文件流馈送到该库。问题是引擎无法在Haiku上找到此库,因为没有版本就没有指向库文件的符号链接。 void CUnixDynamicLoader::DoOpen(const char *lib) {
一个小技巧将所需库的完整路径替换为函数,结果证明这是一个完全可行的解决方案。而且由于引擎多次搜索缺少该库的库,因此将来我会保留加载下一个主要版本的可能性。我希望他们不要破坏其中的API。我遇到的下一个问题是无法确定x86体系结构上的处理器频率,尽管在x86_64上一切正常。在x86上运行时,引擎要求设置名称为SERIOUS_MHZ的环境变量并设定适当的频率,这让我非常惊讶。我尝试这样做,游戏确实开始了,但是由于某种原因,它运行太慢。在很长一段时间里,我一直在爬游戏的源代码,找不到问题的根源,甚至编写了一段代码,使用Haiku API来获取正确的处理器频率并将其代入游戏引擎,这就是它的样子: #include <kernel/OS.h> #include <stdio.h> ... uint64 cpuFreq = 0; uint32 count = 0; get_cpu_topology_info(NULL, &count); if (count != 0) { cpu_topology_node_info *topology = new cpu_topology_node_info[count]; get_cpu_topology_info(topology, &count); for (uint32 i = 0; i < count; ++i) { if(topology[i].type == B_TOPOLOGY_CORE) { cpuFreq = topology[i].data.core.default_frequency; } } delete[] topology; } fprintf(stderr, "%llu\n", cpuFreq);
但这没有帮助。然后,我检查了x86_64上的引擎日志,发现那里的CPU频率通常确定为1 MHz,但是一切正常。继续进一步检查代码,我遇到了__GNU_INLINE_X86_32__ define的拒绝,该定义在针对x86体系结构而不是针对x86_64构建应用程序时自动显示。在此定义之下,隐藏了用于使用SDL2计时器的标志,而不是使用内联汇编程序和rdtsc指令或读取/ proc / cpuinfo文件等各种魔术来获取处理器频率,因此我使该标志被激活并对于x86,这解决了我的问题。最后一个缺陷与我的粗心有关。我在汇编文件中错过了CMakeLists.txt设置-march = native标志,从字面上告诉编译器:生成机器代码块时,请使用计算机处理器上可用的所有复杂的现代指令。 if(NOT PANDORA AND NOT HAIKU) message("Warning: arch-native will be used!") add_compile_options(-march=native) endif() if(HAIKU) if(CMAKE_SIZEOF_VOID_P EQUAL 4)
因此,存储库中的软件包仅聚集在功能最强大的构建服务器下,并拒绝在普通凡人的计算机上运行,并宣誓错误的指令和操作码。禁用此标志并手动添加对MMX,SSE和SSE2指令的支持,不仅解决了此问题,而且还使我们能够在该项目中编译大量的内联汇编程序,该汇编程序在删除该标志后消失了。令我感到非常遗憾的是,Croteam开发人员不接受引擎存储库中的任何修补程序,因此我将所有工作分叉并放在其中:项目源代码:https : //github.com/EXLMOTODEV/Serious-EngineHaikuPorts存储库中已经提供了用于启动“ Serious Sam”游戏的准备安装包。只要记住要下载游戏数据文件即可。<<跳到内容8.移植Vangers游戏
坦白说,直到最近,我还是完全不熟悉这款游戏。这款游戏是在90年代由国内开发工作室KD Lab制作的。但是,专门讨论Haiku操作系统的Telegram IM会议的参与者要求我移植Vangerov并给我一个指向GitHub存储库的链接,该游戏的源位于其中。Haiku的Vanger游戏端口启动器的屏幕快照。将源代码导入Haiku后,我尝试对其进行编译,并且成功了,没有任何特殊问题。我不得不修改一些缺少的头文件以及该游戏引擎所使用的FFmpeg库的路径。我立即开始准备打包源代码,因此我添加了环境变量VANGERS_DATA并将引擎日志移至可写的用户目录。在Qt Creator IDE中将Vanger游戏移植到Haiku的过程。我自己开始游戏,过了一会儿,我欣赏了KD Lab的家伙创造的整个氛围。一段时间后,我开始灵活地将雨云车带到孵化器,把痰液带到Podish,之后我甚至设法将Elik带到第三位。玩了足够的游戏后,我开始根据我上面的资料库为这个游戏准备一个启动器。在Haiku操作系统上运行的Vanger游戏端口。我遇到的第一个问题是可以使用数字发行服务GOG.com和Steam正式获取的游戏数据文件,不想使用该引擎。我不得不联系使用昵称stalkerg并将Wanger移植到Linux的人。他告诉我要替换的文件,以便一切开始并开始工作。我按照他的建议,得到了我所需要的。就像我在上面提到的NXEngine(Cave Story)端口的情况一样,俄语和英语版本在不同的可执行文件中有所不同,但是带有数据文件的目录是通用的,不同之处仅在于脚本。在跟踪狂的尽头,我尝试使用-DBINARY_SCRIPT = Off选项编译游戏引擎,如果它们在游戏数据文件目录中,则它们会在运行时激活这些脚本的动态编译。所有这些使我能够创建一个启动器,在其中可以切换语言。想法是这样的:游戏目录已预先检查,如果没有必要的脚本,则从软件包的内容复制它们,之后便已运行俄语或英语版本的可执行文件。Vanger的游戏端口,已发布在Haiku Depot存储库中。移植Wanger时,我使用了一个有趣的功能,该功能与我喜欢的Haiku共享库有关。游戏引擎依赖于动态库libclunk.so,该库负责实时生成双耳声音。而且,如果在Linux上,我必须动手,将环境变量LD_LIBRARY_PATH替换为该库的路径,以便也保存此变量中的内容,然后在Haiku中像在Windows中那样方便地完成操作。将共享库放在可执行文件旁边就足够了,它将被拾取,唯一的不同是对于Haiku,必须将库放在目录./lib/中。,我认为这可以大大节省时间和精力。因此,我决定不考虑该库的静态编译。项目源代码:https : //github.com/KranX/VangersWanger开发人员接受了我对他们的游戏引擎所做的更改,尽管自从之后在存储库基础架构中发生了最近的问题,仍然可以从HaikuPorts存储库或HaikuDepot程序下载可安装的软件包。将Fedora Linux发行版更新到新版本。<<跳到内容9. Haiku的SDL2库中对话框的实现
在移植我在上面写过的Xash3D和Serious Engine引擎时,我遇到了SDL2库中的一个本地端口,它完全缺少对话框的实现。对话框由两个函数SDL_ShowSimpleMessageBox()和SDL_ShowMessageBox()调用,这些函数可以将任何重要信息(例如有关错误的信息)通知用户。这些对话框的实现可在许多平台和操作系统上使用:Windows,macOS,iOS,X11和Android,但由于某些原因,Haiku缺少该对话框。我决定修复此遗漏并将此功能添加到SDL2库端口。在Haiku API或接口套件框架中,有一个很棒的类BAlert这对于实现此类对话框非常有用。我决定选择它作为基础。唯一困扰我的是,我不确定在BAlert构造的对话框中是否可以放置三个以上的按钮。我还记得上面写过的该类中的内存管理功能:它的对象只能在堆上创建,而不能在堆栈上创建,因为在调用Go()方法和后续的用户操作后,它会删除自身。经过一些实验后,我消除了所有疑问,从此类继承下来,并开始编写实现。Haiku操作系统的SDL2库中对话框的实现。我遇到的第一个困难是,在使用BAlert类的任何对象或其子代时,有必要创建BApplication系统类的实例,显然是为了向app_server注册应用程序以便能够与之交互。我创建了此类的实例,但是当从另一个进程或从创建的窗口调用BAlert对话框时,又遇到了另一个错误,该错误与应用程序不能具有BApplication类的两个对象有关,幸运的是,我找到了解决此问题的方法。 Haiku API具有指向该类当前实例的全局指针BApplication称为be_app,它在Qt框架中的对应对象是一个特殊的qApp宏,该宏还定义了指向当前应用程序对象的指针。因此,只需检查be_app指针是否为NULL 就足够了,如果检查成功,则创建所需的对象。因此,所有这些问题都得到解决。值得注意的是,SDL2库是用C编程语言编写的,正如您所知,Haiku API使用C ++编程语言。因此,应在代码的某些部分涂上外部的“ C”绑定约定,以便链接期间的字符解析没有问题。另外,代替new您应该使用new运算符(std :: nothrow)来检查分配的内存是否为NULL,而不是抛出异常,而SDL2当然不支持该异常。其余的并不复杂。我们编写了几个函数,这些函数以与Haiku API兼容的方式转换SDL2的实体和表示形式,并验证它们是否正常工作。对于各种检查,我扩展了小型测试。,我定期在不同的操作系统上运行,分析结果并评估我的工作。最后,我非常的兴奋,以至于我什至都支持自定义,例如为按钮和对话框的背景设置不同的颜色。 SDL2库API支持此功能,但最初我并不打算实现此类功能。如果程序员决定在该对话框中插入非常长的一行,则在BAlert类对象内部使用的BTextView类对象需要调用参数为true的SetWordWrap()方法击中这样的程序员,并使对话适合屏幕。似乎没有什么比这容易的了:我们使用strlen()函数检查字符串的长度,然后做正确的事情。唯一的问题是SDL2也可以与UTF-8一起使用,这意味着strlen()函数将返回字节数,而不是字符数。 Haiku API和BString字符串类来了急救,它具有CountChars()方法,该方法允许您以字符而不是字节来查找字符串的长度: bool CheckLongLines(const char *aMessage) { int final = 0;
此函数检查消息文本中超过120个字符的行,如果有,则返回true。至于UTF-8,仍然有片刻,某些Haiku系统字体不支持汉字。因此,例如,您不能在窗口标题中设置任何中文题字。但是,俄语文本的安装没有问题。在准备软件包时,我遇到了x86_gcc2体系结构的构建错误,该错误已在SDL2库配方中激活。原来,最老的GCC 2.95编译器无法猜测所注释的代码与以下代码等效: rgb_color ConvertColorType(const SDL_MessageBoxColor *aColor) const {
因此,我不得不用旧样式重写此片段,并且仍然直接在类的声明中删除类中某些常量的初始化,旧编译器也不喜欢这样。我已将用于实现SDL2对话框的补丁发送到HaikuPorts存储库,因此现在Xash3D和Serious Engine引擎可以正确地向用户发出任何信息,例如有关错误的信息。但是我还没有联系过SDL2开发人员,但是将所有补丁从HaikuPorts存储库转移到上游SDL2库是很好的。虽然我们的补丁转移工作稍微复杂一点,因为最近的重命名前缀功能BE_ *上HAIKU_ *,但它不是这样一个严重的问题。<<跳到内容10.移植我的Cool Reader叉子
我一直以来我开发一个叉程序酷阅读器,以书面瓦迪姆洛帕廷(Buggins),相当于一篇文章关于它可以在我的网站。在该文章的评论中,我的博客的读者一直在退订,他们要么是想在自己喜欢的阅读电子书的应用程序中看到一些新功能,要么是想解决已经实现的程序功能中的错误和不足。我的Cool Reader前叉在Haiku上运行。在HaikuPorts存储库中,我找到了一个用于构建原始Cool Reader程序的方法,但是,由于SourceForge资源不断发生某些变化,因此该方法无法使用,因为该应用程序的源代码不可下载。然后,我决定将叉子作为Cool Reader的新版本转移到HaikuPorts存储库。我将所有Gerasim的修补程序都放在了代码上,解决了配方中的一些缺点,并基于此创建了一个新的程序包,该程序包已可供所有Haiku用户使用。您可以在以下GitHub存储库中找到我的Cool Reader fork的源代码:项目源代码:https : //github.com/EXLMOTODEV/coolreader我遇到的唯一问题是在传输Gerasim补丁时不准确。除了__HAIKU__ 定义外,还在构建系统的其他地方设置了_LINUX 定义,并且由于在大多数情况下,源代码清单中的最后一个是第一个,因此条件编译让我失望了。根据预处理程序优先级规则,对于Haiku来说,正是由_LINUX define构成的那些代码被编译了,尽管我需要完全不同的东西。但是尽管如此,该程序仍可以启动并运行,但仅将其设置保存在需要的位置。我正确地确定了优先级,重建了软件包,问题得到了彻底解决。<<跳到内容11. KeymapSwitcher程序的完成
最近,许多流行的操作系统已切换到新的键盘快捷键Meta / Opt / Cmd / Win + Space来切换键盘布局。在我看来,这很方便,因为我现在不需要更改任何内容并对其进行配置。您可以坐在运行带有GNOME 3 shell的macOS,Windows或Linux的任何计算机上,这种方便的组合更改输入语言的方法随处可见。甚至Android移动操作系统也具有其类似物。总的来说,我很久以前切换到此键盘快捷键,并且已经习惯了。非常遗憾,KeymapSwitcherHaiku附带的,不允许我设置这种方便的组合键来切换布局,这就是为什么在此操作系统中使用文本时,我经常感到不便。因此,我决定对该应用程序进行一些修改,并开始搜索其源代码。事实证明,尽管该程序包含在Haiku发行版中,但它是与操作系统本身的源代码分开提供的。另外,该应用程序在HaikuPorts存储库中可用,并且也通过该库进行更新。据我了解,Haiku中未包含KeymapSwitcher,因为它计划实现用于更改键盘布局的特殊API,并且有一天该程序的需求将完全消失。Haiku上的KeymapSwitcher,带有流行的键盘快捷键,用于切换键盘布局。尽管我对KeymapSwitcher代码的复杂性感到害怕,但由于注释,我很快找到了正确的位置,并在程序代码中引入了一个小补丁,这极大地方便了我在Haiku中键入任何文本。我无法克服的唯一微小缺陷是,需要释放Opt键才能切换语言。也就是说,按住Opt并且在所选语言之间切换的空间将不起作用。但这绝对不会干扰键入期间的语言切换,因此我将修补程序发送到程序存储库并更新了HaikuPorts中的应用程序包,此后,新版本的KeymapSwitcher可供所有Haiku用户安装。项目源代码:https : //github.com/HaikuArchives/KeymapSwitcher我希望我不是该键盘快捷方式切换键盘布局的唯一用户。<<跳到内容12.结论
学习Haiku API并解决由于为此操作系统移植新的和更新的现有应用程序而引起的各种奇特的问题,这给我带来了很多宝贵的经验和乐趣。我能够在一些大型项目的源代码存储库中推广Haiku支持补丁,并结识了一些与这个漂亮的操作系统有关的有趣的新人。在Haiku操作系统上运行的各种应用程序。我衷心希望将来能够成功解决所有当今的问题,例如缺乏3D硬件加速和流行的浏览器,以及对现代硬件的不良支持,并且Haiku将获得开发者和用户的新宠,他们将欣赏其独特的功能和原始设计。幸运的是,发展远非止步不前,今天在此操作系统的本地论坛上,出现了有关3D加速和GTK + 3库移植的热门话题,并且在HaikuPorts存储库中讨论了移植QtWebEngine组件的可能性。。 GTK + 3的端口可能会导致运行和工作的Firefox和铬,和QtWebEngine流行的浏览器允许使用眨眼引擎在现代浏览器,基于Qt框架,,如能够水獭浏览器或Falkon。例如,现在我已经可以向那些笔记本电脑或上网本较弱的人推荐这种操作系统,而不是Lubuntu发行版或Windows XP。您会惊讶于它的速度和响应速度。是的,由于浏览器过旧以及与之相关的一些故障,您必须限制自己访问某些网站,但是对于大多数情况,在旧硬件上,此限制没有任何意义。我所有的端口和改进都已经发布,可以供所有Haiku用户安装。对源代码的所有更改都可以在其原始许可证下的相应存储库中找到。在这项工作中,我使用了大量材料,主要内容将在下面的有用链接中突出显示。非常感谢stackoverflow.com和google.com的支持。1. Haiku操作系统的官方网站。2. Haiku操作系统的官方论坛。3. Haiku用户的官方文档。4. Haiku开发人员的正式文档。5. Haiku图形用户界面功能的描述。6.有关为Haiku应用程序创建图标的建议。7. Icon-O-Matic程序的说明及其使用技巧。8.矢量HVIF图标格式的说明。9. Interface Kit框架的正式文档。10. Locale Kit框架的正式文档。11.关于Haiku的应用程序本地化方面的文章。12. Layout API的官方文档。13.一系列文章描述了Haiku中Layout API的实现。14. Haiku操作系统的源代码的GitHub存储库。15. HaikuPorts食谱树的GitHub存储库。16.现成的HPKG软件包Haiku Depot Web的存储库的Internet版本。17. INSTEAD开发人员Peter Kosykh博客上的一篇有趣的文章“ Haiku:lamp geek-OS”。18. INSTEAD开发人员博客Pyotr Kosykh上的“ Haiku:沉浸式”文章。19. DarkWyrm的编程课程“学习Haiku编程”。20.来自DarkWyrm的“ Haiku编程”编程课程的课程。21.出版物“ Hai句上有生命吗?”在我的资源Linux.org.ru上。22. Telegram IM会议,专门讨论Haiku操作系统。祝贺所有资源用户habr新年快乐,并祝他们圣诞节快乐!在新的2019年祝你们好运!<<跳到内容