Sistema operativo Haiku: portabilidad de aplicaciones y creación de paquetes

https://sudonull.com/post/6296-Haiku-operating-system-porting-applications-and-creating-packages 

En otoño de este año, después de 6 años de desarrollo, se lanzó la primera versión beta del sistema operativo Haiku R1/beta1. Llevo mucho tiempo siguiendo este interesante proyecto, que tiene como objetivo la reconstrucción y posterior desarrollo del sistema BeOS que existió en 1994-2000. Por lo tanto, tan pronto como vi noticias sobre el lanzamiento de la versión beta de Haiku en los sitios de noticias de TI, inmediatamente decidí ver qué se agregaba a este lanzamiento tan esperado. Después de instalar el sistema en un VirtualBoxmáquina virtual y un poco de familiarización con su funcionalidad principal, pensé que sería bueno ayudar a la comunidad OpenSource, que está desarrollando este sistema operativo hoy. Decidí comenzar con lo que he ganado un poco de experiencia: portar algunos proyectos de juegos.



Sistema operativo de escritorio Haiku.

Más tarde intenté modificar algunas aplicaciones y bibliotecas ya existentes. Esta es mi pequeña actividad en varios repositorios de código abierto a los que se dedicará este artículo. En él, describiré sucesivamente los problemas que encontré y les contaré los métodos para resolverlos. La mayoría de los parches que se hicieron en el curso de este trabajo, traté de enviar proyectos existentes aguas arriba para brindar soporte para Haiku e interesar a sus desarrolladores en la existencia de sistemas operativos alternativos.

El sistema operativo Haiku utiliza un núcleo híbrido, que es una implementación de la arquitectura micronuclear con la capacidad de cargar dinámicamente los módulos necesarios. Se basa en la bifurcación del kernel NewOS , que fue desarrollado por un ex ingeniero de Be Inc. , por Travis Geiselbrecht. A día de hoy, este desarrollador está trabajando en Google en un kernel llamado Zircon para el nuevo sistema operativo de Google Fuchsia , pero esa es otra historia. Entonces, dado que los desarrolladores de Haiku declaran compatibilidad binaria con BeOS, se ven obligados a mantener no dos ramas arquitectónicas familiares para todos, sino tres: x86_64, x86 y x86_gcc2. La última arquitectura es la carga de compatibilidad con el antiguo compilador. CCG2.95. Gracias a él, es posible ejecutar aplicaciones escritas para el sistema operativo BeOS original. Desafortunadamente, debido a esta carga de compatibilidad, los desarrolladores de Haiku no pueden usar las funciones avanzadas del lenguaje de programación C ++ en las API del sistema. Sin embargo, preparan imágenes de instalación solo para dos arquitecturas: x86_64 y x86. El hecho es que la distribución de Haiku para x86 es híbrida: a pesar de que todos los componentes del sistema están construidos bajo x86_gcc2 para proporcionar compatibilidad binaria, el usuario tiene la oportunidad de instalar o construir cualquier aplicación moderna que haya sido hecha con compiladores y arquitectura x86. La distribución x86_64 Haiku es completamente de 64 bits y no tiene la capacidad de ejecutar aplicaciones BeOS y Haiku de 32 bits. Pero, hay compatibilidad a nivel de API, por lo tanto, si tiene el código fuente de la aplicación en BeOS o Haiku x86, puede compilarlo fácilmente en Haiku x86_64 y todo debería funcionar. Se recomienda una imagen de sistema operativo x86_64 para la instalación en hardware real, si no necesita soporte para ninguna aplicación BeOS específica o aplicaciones Haiku de 32 bits.

Cabe decir que este sistema operativo tiene soporte parcial para el estándar POSIX . Esta base lo hace similar a los sistemas similares a UNIX y facilita la migración de su software. El lenguaje de programación principal es C ++, se usa activamente, ya que las API públicas de Haiku persiguen principalmente un paradigma de programación orientado a objetos. Sin embargo, nadie prohíbe el uso del lenguaje de programación C, solo que en la mayoría de los casos tendrás que escribir la capa de compatibilidad adecuada. La interfaz de software del sistema operativo se agrupa en marcos de sistema separados que son responsables de una oportunidad particular, por ejemplo, la interfaz o el soporte de red. Esto es un poco como lo que está en macOS o en el marco QtEs necesario señalar que este sistema operativo es de un solo usuario, aunque hay algunos avances para proporcionar un modo de trabajo multiusuario para los desarrolladores de Haiku.

No puedo compartir con los lectores de este artículo, la experiencia positiva de usar el sistema avanzado de gestión de ventanas de aplicaciones, que está disponible en Haiku. En mi opinión, es uno de los más convenientes y de su tipo es el sello distintivo de este sistema operativo.


Gestión avanzada de ventanas en el sistema operativo Haiku: compatibilidad con mosaicos y pestañas.

Las ventanas se pueden unir en pestañas, como se hace en los navegadores modernos, unirlas entre sí y cambiar su tamaño convenientemente. Se admiten mosaicos simples , transferencia de contexto de algunas aplicaciones de una ventana a otra y replicantes . Para obtener más información sobre todas las funciones del sistema de ventanas locales, consulte la documentación oficial , también se describen todas las teclas de acceso directo necesarias.

No escribiré en este artículo una descripción completa de todas las características y capacidades de Haiku, ya que aquellos que estén interesados ​​​​podrán encontrar fácilmente la información necesaria de forma independiente en Internet.


1. Paquetes y repositorios en Haiku


En comparación con el BeOS original, Haiku tiene una innovación importante: el sistema de administración de paquetes, que incluye varias herramientas para obtener e instalar software de varias fuentes. Dichas fuentes pueden ser repositorios oficiales de Haiku y HaikuPorts ., repositorios informales y solo paquetes HPKG separados y especialmente preparados. Tales oportunidades para instalar y actualizar software se conocen desde hace mucho tiempo en el mundo de los sistemas operativos similares a Unix, pero ahora todo su poder y conveniencia han llegado con éxito a Haiku, que no puede sino hacer felices a los usuarios comunes de este sistema operativo. Gracias al administrador de infraestructura construido alrededor del administrador de paquetes, ahora cualquier desarrollador puede transferir fácilmente una nueva aplicación de código abierto o modificar una existente, luego agregar los resultados de su trabajo al repositorio de puertos del software HaikuPorts, después de lo cual estarán disponibles para todos. Usuarios de haikus. Como resultado, el ecosistema resultante se parece al de macOS con su Homebrew , FreeBSD con sus puertos. , ventanas con MSYS2 o Arch Linux con su AUR 'om.

Una herramienta para crear paquetes y migrar software, llamada HaikuPorter , viene por separado del sistema operativo y se instala en un pequeño manual ubicado en el repositorio de GitHub. Después de instalar esta utilidad, todo el árbol de recetas se descarga desde el mismo GitHub y el desarrollador trabaja en él. La receta es un script regular de Shell con instrucciones sobre las cuales HaikuPorter construirá el paquete HPKG requerido. Cabe destacar que la herramienta en sí está escrita en el lenguaje de programación Python .2, interactúa estrechamente con el sistema de administración de paquetes existente, y para corregir cambios en el código fuente del software y generar un conjunto de parches, en su interior utiliza una herramienta estándar: Git . Gracias a esta pila de tecnologías, es muy fácil y sencillo crear recetas para ensamblar paquetes HPKG y conjuntos de parches en software en forma de archivos de conjunto de parches. En la mayoría de los casos, tuve que usar solo tres comandos cuando trabajaba con HaikuPorter:

alias hp="haikuporter -S -j4 --get-dependencies --no-source-packages"
hp libsdl2
hp libsdl2 -c
hp libsdl2 -e

El primer comando simplemente recopila el paquete seleccionado, el segundo comando borra el directorio de compilación y el tercero crea o actualiza el conjunto de parches de acuerdo con sus cambios, que se registraron en el repositorio Git del directorio de trabajo a través de confirmaciones.

Por lo tanto, para publicar un paquete en el repositorio de HaikuPorts y ponerlo a disposición de todos los usuarios de Haiku, el desarrollador debe instalar HaikuPorter, expandir el árbol de recetas, compilar localmente el paquete HPKG y probarlo, luego realizar una confirmación en su bifurcación de la receta. árbol, luego dibujar Solicitud de extracciónen github. El trabajo publicado debe ser considerado por los desarrolladores de Haiku, luego de lo cual deciden verter sus cambios en el repositorio o enviarlos para su revisión. Si se aceptan los cambios, el mismo HaikuPorter instalado en el servidor de compilación ensamblará el paquete de forma remota y lo publicará automáticamente en el repositorio.

Se agregó un programa especial HaikuDepot a la versión beta de R1/beta1 del sistema operativo Haiku, que le permite trabajar con paquetes y repositorios a través de una interfaz gráfica de usuario, en lugar de comandos de consola en la terminal.


El programa HaikuDepot ejecutándose en el sistema operativo Haiku.

Gracias a esta herramienta, los usuarios de Haiku inexpertos y novatos pueden administrar convenientemente su base de paquetes. Cabe señalar que esta aplicación no es solo un shell de GUI sobre el administrador de paquetes existente, sino que también implementa funcionalidades adicionales. Por ejemplo, los usuarios autorizados pueden calificar y escribir reseñas de paquetes disponibles para la instalación. Además, HaikuDepot tiene un sitio web especial de Haiku Depot que le permite ver los cambios en la base de paquetes en Internet o descargar paquetes HPKG individuales.


2. Primeros pasos: portar el juego Adamant Armor Affection Adventure


Después de familiarizarme con la funcionalidad del sistema operativo en la máquina virtual VirtualBox, decidí evaluar el trabajo de la biblioteca SDL2 en ella y transferir el juego Adamant Armor Affection Adventure a Haiku, sobre el cual escribí anteriormente en la plataforma Android. La construcción del programa no requirió ningún cambio en el código fuente, solo instalé todas las herramientas necesarias, bibliotecas, sus archivos de encabezado del repositorio e hice lo siguiente:

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 .

Dado que Haiku tiene el POSIX, el defayny -D__linux__ o -D__unix__ resuelve muchos problemas asociados con la definición de una plataforma. Sin embargo, vale la pena señalar que es mejor abandonar su uso e implementar soporte para Haiku en el código fuente del proyecto, si hay problemas similares con el ensamblaje. Llamar a la utilidad del sistema finddir con un argumento específico le permite obtener la ruta correcta a los archivos de encabezado para diferentes arquitecturas.

Entonces, después de ejecutar los comandos anteriores, compilé un archivo ejecutable que comenzó perfectamente y el juego funcionó bien. Pensé que sería genial preparar un paquete HPKG autosuficiente con el juego y para ello me adentré en Internet en busca de la información que necesitaba. Entonces no conocía ninguna herramienta conveniente para portar software, como HaikuPorter, sobre la que escribí en la sección anterior, así que para lograr mi objetivo decidí hacer trampa y desmontar cualquier paquete del sistema para ver cómo funciona por dentro y listo. por analogia.

En Internet, encontré la información deseada , luego descomprimí un paquete de sistema aleatorio usando el archivador Expander integrado en el administrador de archivos local, encontré .PackageInfoArchivo , lo editó y, de acuerdo con la estructura de su aplicación, modificó los archivos. Luego simplemente ejecuté los comandos para compilar el paquete HPKG e instalarlo en el sistema:

package create -C AAAA/ aaaa.pkg
pkgman install aaaa.pkg

Desafortunadamente, el lanzamiento del juego desde el menú "Aplicaciones" no tuvo éxito. Después de ejecutar el archivo ejecutable en la terminal, recibí un error que decía que era imposible encontrar los archivos de datos necesarios para el inicio y el funcionamiento de la aplicación. Al mismo tiempo, si va al directorio del paquete de la aplicación en la terminal, todo se iniciará normalmente. Esto me dio la idea de que cuando inicias el juego desde el menú, debes hacer un cambio forzado en el directorio de la aplicación. Esto se puede hacer con un script de shell o cambiando la fuente del juego. Elegí la segunda opción y agregué algo similar a este código:

#ifdef __HAIKU__// To make it able to start from Deskbar
    chdir(dirname(argv[0]));
#endif

Al comienzo de la función de inicio principal () , que resolvió completamente este problema y el paquete resultó ser viable. En los comentarios sobre las noticias sobre el lanzamiento de la versión beta de Haiku en Linux.org.ru, dejé un enlace a mi paquete ensamblado y le pedí a alguien que me enviara a algunas comunidades activas de usuarios de este sistema operativo, luego me fui a la cama.


El puerto del juego Adamant Armor Affection Adventure, que se ejecuta en el sistema operativo Haiku.

Por la mañana le escribí un correo electrónico a una persona usando el apodo 3dEyes . Como se supo más tarde, Gerasim Troyeglazov , uno de los desarrolladores activos de Haiku y el autor del puerto del marco Qt para este sistema operativo, se escondía detrás de este nombre. Me mostró el repositorio HaikuPorts y me dijo cómo usar la utilidad HaikuPorter. Además, escribió una receta para construir el paquete Adamant Armor Affection Adventure HPKG y lo agregó a HaikuDepot.

Después de analizar todos los cambios realizados por este desarrollador, noté que había algunas fallas en mi paquete ensamblado manualmente, por ejemplo, la configuración no se guardaba porque los directorios montados de los paquetes instalados no tenían la capacidad de escribir. Este problema con la configuración de escritura o guardar en su paquete se resolvió elegantemente con la ayuda de enlaces simbólicos en un directorio grabable especial para guardar datos de usuario. Mi paquete tampoco tenía su propio icono original.

Además, aprendí que en Haiku no hay aceleración de hardware de gráficos 3D y el mismo OpenGL se dibuja mediante programación utilizando la potencia de la CPU. Para aplicaciones gráficas pesadas esto, por supuesto, no es bueno, pero para juegos antiguos es más que suficiente. Incluso decidí verificar específicamente el paquete del juego e instalé Haiku en mi vieja computadora portátil, es decir, en hardware real. Para mi sorpresa, la imagen de Adamant Armor Affection Adventure se procesó tan rápido que si no me hubieran informado sobre la falta de aceleración de hardware, no me habría dado cuenta de que mi procesador realiza el procesamiento.

Código fuente del proyecto: https://github.com/EXL/AdamantArmorAffectionAdventure

Pospuse la creación manual de paquetes HPKG hasta tiempos mejores y cambié por completo a usar la herramienta HaikuPorter y escribir recetas. Pero a veces hay situaciones en las que se requiere volver a armar manualmente. Por ejemplo, si HaikuPorter ha configurado la versión "nocturna" de Haiku demasiado alta en el archivo .PackageInfo , el paquete debe probarse en la versión de lanzamiento del sistema operativo. Vale la pena señalar que fue gracias a la capacidad de respuesta y la experiencia de Gerasim que pude comprender muchas de las complejidades de la creación de paquetes para el sistema operativo Haiku y continuar con mi trabajo.



3. Finalización del puerto existente NXEngine (Cave Story)


Me sorprendió muchísimo encontrar en el repositorio de HaikuPorts una receta que hacía referencia a mi fork del motor NXEngine para el juego Cave Story , que llevaba analizando mucho tiempo en mi blog. La receta y los parches fueron preparados por un desarrollador llamado Zoltán Mizsei , quien usa el apodo de extrowerk y es el mantenedor activo de muchos paquetes para Haiku.

El análisis de superficie, la instalación del paquete y el lanzamiento de la aplicación revelaron los mismos problemas que describí en la sección anterior de este artículo: guardar el juego no funcionó, la configuración tampoco se guardó y, además, el paquete no tenía el icono original. Decidí corregir estas deficiencias y comencé a trabajar en el parche, primero integrando todo el trabajo del extrowerk. Escribí el Makefile original para el sistema operativo Haiku y corregí la grabación y el guardado de varios datos de usuario.


El puerto del juego Cave Story basado en el motor NXEngine, lanzado en el sistema operativo Haiku.

Dado que el juego asumió versiones en ruso e inglés con un conjunto diferente de archivos ejecutables y archivos de datos, decidí hacer un paquete general que combine dos versiones a la vez y seleccione automáticamente la necesaria según el idioma del sistema elegido por el usuario. Esto fue implementado por el script de shell más simple:

#!/bin/bashif [[ `locale -l` == ru* ]] ;
then
    EXE="`finddir B_SYSTEM_APPS_DIRECTORY`/NXEngine/RUS/Cave Story"else
    EXE="`finddir B_SYSTEM_APPS_DIRECTORY`/NXEngine/ENG/Cave Story"fi"$EXE"$@

Este script se inicia cuando se selecciona el elemento del juego en el menú "Aplicaciones" y determina la configuración regional actual del sistema. En el caso de que el usuario elija el ruso como idioma del sistema, se lanzará la versión rusa del juego y, en todos los demás casos, la versión en inglés.

Pero con la creación de los íconos originales para la aplicación tuvo que ser bastante complicado. El hecho es que en el sistema operativo Haiku, solo se permiten iconos vectoriales de un formato HVIF especial , que se establecen como atributos del sistema de archivos Be File System . En la documentación oficial, hay dos grandes manuales dedicados a crear tus propios iconos para aplicaciones: el primer manualdescribe el estilo y el diseño, y el segundo manual explica en detalle cómo utilizar el software del sistema Icon-O-Matic para crear iconos.

Icon-O-Matic le permite importar archivos SVG simples y exportar el icono resultante al formato necesario para HaikuPorter, llamado HVIF RDef, que es el mismo HVIF, pero convertido a texto. Los archivos RDef pueden contener no solo imágenes, sino también información adicional, por ejemplo, la versión de la aplicación y su descripción. Algo estos archivos se parecen a los archivos RES utilizados en Windows. Los siguientes comandos en la receta compilan archivos RDef y establecen el resultado en atributos especiales:

rc nxengine-launcher.rdef
resattr -o "$appsDir/NXEngine/Cave Story" nxengine-launcher.rsrc
addResourcesToBinaries $sourceDir/build/nxengine-rus.rdef "$appsDir/NXEngine/RUS/Cave Story"

Además, las recetas definen la función addResourcesToBinaries para automatizar este trabajo. El problema del programa Icon-O-Matic es uno, pero muy serio: esos archivos SVG que guarda el popular editor de vectores Inkscape, no se abren o se importan sin el soporte de algunas funciones necesarias, por ejemplo, degradados. Por lo tanto, una búsqueda de aventura con la conversión de imágenes rasterizadas en vectores mediante el uso de varios convertidores en línea y fuera de línea pagos y gratuitos, y luego abriendo los archivos SVG resultantes en Icon-O-Matic, fracasé miserablemente. Más tarde, resolví el problema de abrir archivos SVG y encontré una solución alternativa, pero escribiré sobre esto a continuación. Mientras tanto, decidí usar las funciones estándar de Icon-O-Matic y dibujar un ícono por mi cuenta. Después de media hora de trabajo en la copia impresa de píxeles, obtuve el siguiente arte:


El programa estándar es Icon-O-Matic en el sistema operativo Haiku.

Sí, utilicé un editor de vectores para crear una imagen en el género Pixel Art. En mi opinión de aficionado, una persona poco versada en arte resultó bastante bien. Guardé este ícono en el formato correcto, preparé todos los cambios, actualicé la receta y envié todo al repositorio de HaikuPorts.

Código fuente del proyecto: https://github.com/EXL/NXEngine

Envié los paquetes resultantes por si acaso al sitio de fans del juego Cave Story (Doukutsu Monogatari) , cuya administración agregó el sistema operativo Haiku al sección de descargas.


4. Portando el juego de Gish


El siguiente proyecto que decidí transferir a Haiku fue Gish , que anteriormente transfirí a Android. En el repositorio de HaikuPorts había una receta para una implementación libre sin terminar del juego llamada Freegish , así que decidí agregar allí el juego original, pero sin los archivos de datos, ya que estos, a diferencia del motor, se suministran por separado y no son gratuitos en todo.


El puerto del juego Gish, lanzado en el sistema operativo Haiku.

No tuve problemas particulares con la migración de este juego. El archivo ejecutable se ensambló inmediatamente después de la ejecución de los siguientes comandos de compilación:

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 .

A continuación, implementé la capacidad de iniciar el juego desde el menú "Aplicaciones" y brindé soporte para almacenar datos de usuario en un directorio dedicado y de escritura:

char* getHaikuSettingsPath(){
    char path[PATH_MAX];
    find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, path, sizeof(path));
    strcat(path, "/Gish/");
    return strdup(path);
}

La función getHaikuSettingsPath () que utiliza la función find_directory () de la API de Haiku genera la ruta completa al directorio que necesito.

El código fuente del proyecto: https://github.com/EXL/Gish

Quedaba por resolver la siguiente pregunta: ¿cómo debería el usuario elegir el directorio con los archivos originales del juego Gish? El problema podría resolverse usando Shell-scripts y la utilidad del sistema de alerta , pero decidí abordar este problema más a fondo e implementar un iniciador de GUI conveniente usando la API de Haiku y el marco del kit de interfaz .



5. El proyecto BeGameLauncher, que te permite crear rápidamente lanzadores para juegos.


Mi proyecto BeGameLauncher se decidió escribir en C ++ el antiguo estándar de 1998, utilizando herramientas nativas del sistema operativo para crear aplicaciones con una interfaz gráfica de usuario. Dado que los nombres de muchos programas para Haiku y BeOS comienzan con la corrección "Be", también decidí elegir ese nombre para el proyecto. Decidí comenzar con una introducción al marco del kit de interfaz, que forma parte de la API de Haiku. Además de la documentación suficientemente detallada en el sitio web oficial de Haiku, encontré dos cursos de lecciones simplemente excelentes de DarkWyrm , que permiten al desarrollador novato comprender rápidamente cómo funcionan ciertas clases del sistema. El primer curso se llama Aprendiendo a Programar con Haikuy al principio toca los conceptos básicos del lenguaje de programación C ++, que será muy útil para los programadores novatos. El segundo curso se llama Programación con Haiku y está destinado a aquellos que ya están familiarizados con C ++ y tienen un conocimiento básico de este lenguaje. Ambos cursos tratan sobre los aspectos más diversos de la API de Haiku y, por lo tanto, serán de gran ayuda para cualquiera que quiera comenzar a crear aplicaciones para este sistema operativo.

Después de leer este excelente material en diagonal, me hice una impresión general de la API de Haiku y comencé a considerar mis acciones futuras. Ya tenía algo de experiencia en el desarrollo de aplicaciones usando el marco Qt, que también está escrito en el lenguaje de programación C ++ y usa el paradigma orientado a objetos de creación de programas. Entonces, la API de Haiku es muy similar a ella, excepto por la ausencia de un sistema de señales y ranuras, por lo que a menudo realizaré algunos paralelismos y comparaciones con Qt. Además, vale la pena señalar el uso del principio de programación dirigida por eventos , que es común en la API de Haiku, que permite que varias entidades interactúen entre sí mediante la transmisión de eventos o mensajes. Un análogo de la clase QEvent aquí es la clase BMessage , en torno al cual se construye el sistema de interacción de objetos. Una instancia de la clase BMessage generalmente obtiene un número único que le permite identificar al remitente y su acción en el filtro de eventos general.

Para mi proyecto, fue necesario seleccionar las clases API de Haiku apropiadas que permitieran implementar la funcionalidad concebida. Primero, para iniciar una aplicación externa, era necesario encontrar un análogo de la clase QProcess o la función POSIX execve () , que, por cierto, también funciona bien en el sistema operativo Haiku, pero decidí que usar herramientas nativas sería ser preferible, pero por si acaso la posibilidad de ejecutar aplicaciones a través de la función POSIX. clase hermanoLa comunicación entre procesos es muy adecuada para este propósito. Encontró el método Launch () apropiado , que le permite establecer la ruta al archivo ejecutable y pasarle argumentos. Dado que el iniciador debería poder guardar algunos parámetros, por ejemplo, un directorio seleccionado por el usuario con archivos de datos del juego, necesitaba una clase que hiciera todo esto. En Qt, esta clase tiene el nombre QSettings , y en la API de Haiku, como me sugirió Gerasim, hay una clase BMessage que ya me es familiar. que tiene una característica muy útil. La cuestión es que la información de esta clase se puede serializar fácilmente y, por ejemplo, guardar en el disco. Esto es muy conveniente y a menudo se usa para registrar datos de usuario en programas, por lo que elegí esta clase para guardar la configuración en mi proyecto para la implementación de lanzadores. Desafortunadamente, la API de Haiku no encontró un análogo de la clase QDebug , por lo que la salida de depuración que necesitaba durante el proceso de desarrollo simplemente se envió a stderr usando la función fprintf () del lenguaje de programación C estándar:

// .h#if __cplusplus >= 201103L#define BeDebug(...) fprintf(stderr, __VA_ARGS__)#elseexternvoidBeDebug(constchar *format, ...);
#endif// __cplusplus == 201103L// .cpp#if __cplusplus < 201103L#include<cstdarg>voidBeDebug(constchar *format, ...){
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
}
#endif

Envolví esta función en la entidad BeDebug() , que es conveniente para mí, que, según el estándar del idioma elegido, es una macro o también una función. Esto se hizo porque C ++ 98 no admite macros con un número variable de argumentos.

Aún en el marco de Qt, hay una clase QMessageBox útil a través de la cual puede crear un diálogo modal con cualquier información a la que el usuario deba prestar atención, por ejemplo, un error o una advertencia. La API Haiku tiene una clase BAlert para este propósito ., cuya implementación es algo diferente de lo que está disponible en Qt. Por ejemplo, un objeto de esta clase debe crearse en el montón, no en la pila, porque después de alguna acción del usuario, debe eliminarse a sí mismo. En cuanto a las otras clases de la interfaz gráfica, aquí no tuve absolutamente ninguna dificultad y encontré todo lo que necesitaba sin ningún problema.

Ahora debería haber pensado en una arquitectura de proyecto simple. Decidí detenerme en la creación de una biblioteca estática en la que habría dos clases diseñadas para heredar de sus propias clases derivadas. La primera y más importante clase, BeLauncherBase , es responsable de crear la ventana principal del lanzador, transferir todos los parámetros del usuario y brinda la posibilidad de agregar sus propios elementos de GUI. La segunda clase, BeAboutWindow , simplemente se encarga de abrir el cuadro de diálogo "Acerca del programa..." con información que se muestra en una ventana separada. Así, un programador para crear su propio lanzador, por ejemplo, para jugar a Gish, necesita realizar dos sencillos pasos:

classGishAboutWindow :public BeAboutWindow
{
    ...
};
classGishLauncher :public BeLauncherBase
{
    ...
};
intmain(void){
    BeApp *beApp = new BeApp(SIGNATURE);
    GishLauncher *gishLauncher = new GishLauncher(BeUtils::GetPathToHomeDir());
    beApp->SetMainWindow(gishLauncher);
    beApp->Run();
    delete beApp;
    beApp = NULL;
    return0;
}


Primero, cree una función de inicio adecuada main () , y segundo, simplemente herede de las dos clases enumeradas anteriormente e implemente los métodos necesarios en ellas. Después de eso, compilamos el archivo C ++ resultante con un enlace a mi biblioteca estática y nuestro lanzador para el juego Gish está listo.


El diálogo "Acerca del programa..." en el lanzador de puertos del juego Gish.

A continuación, pensé en cómo transferir parámetros desde mi lanzador al propio motor o al archivo ejecutable del juego. Solo vi dos formas de resolver este problema. La primera forma era cambiar las variables de entorno. En la práctica, el iniciador, después de hacer clic en el botón "Ejecutar", simplemente coloca todos los parámetros en las variables de entorno a través de llamadas a la función setenv () , y el motor del juego luego lee estos parámetros usando la función getenv () , que parece bastante simple. El único problema que podía surgir aquí era en la clase BRoster y su método de Launch(): No sabía si la aplicación iniciada con esta clase heredará todas las variables de entorno que se establecieron en el lanzador. Después de un pequeño experimento, se confirmó la herencia de las variables de entorno e implementé completamente este método en mi proyecto. La segunda forma de resolver el problema era establecer parámetros de línea de comandos especiales. En la práctica, el iniciador simplemente agregó todas las configuraciones a los argumentos apropiados y llamó al archivo ejecutable de la aplicación con ellos. Pero el motor del juego ya tenía que procesarlos de forma independiente, lo que creaba algunas dificultades. Por ejemplo, si el juego no asumía la posibilidad de especificar la ruta a los archivos del juego a través de los parámetros de la línea de comandos, entonces era necesario modificar el analizador de argumentos en el propio motor. A pesar de estos problemas, Implementé esta forma de interacción y como resultado recibí una excelente oportunidad de combinar todo junto. Esto me permitió crear en algunos lanzadores una cadena especificando argumentos personalizados.

Cuando todo estuvo diseñado, decidí elegir un sistema de montaje para mi proyecto. Solo se consideraron dos opciones: Makefile "on steroids" y CMake . En el primer caso, los desarrolladores del sistema operativo Haiku prepararon un conveniente motor de archivos MAKE.paquete en el que recopilaron todas las funciones necesarias que el desarrollador habría encontrado cuando comenzó a escribir una aplicación en la API de Haiku, por ejemplo, generar traducciones automáticamente y compilar recursos de la aplicación. Pero no soy de los que buscan formas fáciles, así que elegí CMake y le transfirí algunos desarrollos del paquete makefile-engine. Como resultado, el script de ensamblado monstruoso resultante se puede ver en el repositorio del proyecto, un enlace al que dejaré a continuación.


Captura de pantalla del juego de lanzamiento de puerto Gish para Haiku.

Me gustaría escribir algunas palabras sobre la localización de aplicaciones. En el marco de Qt, hay una función contenedora tr () conveniente , dos utilidades auxiliares lrelease y lupdate , que se dedican a generar archivos de traducción. Incluido con el marco está disponible incluso un programa especial Qt Linguist con una conveniente interfaz gráfica de usuario diseñada para traductores. Las herramientas de la API de Haiku para localizar aplicaciones son menos convenientes y más arcaicas. Se propone envolver las líneas que se traducirán en una macro especial B_TRANSLATE () y agregar la definición B_TRANSLATION_CONTEXT al archivo fuente que separa un grupo de cadenas traducibles de otro. Después de eso, debe hacer algo muy extraño: configure el preprocesador del compilador con el indicador -DB_COLLECTING_CATKEYS en absolutamente todos los archivos fuente del proyecto, haga algo de magia con la utilidad grep y, finalmente, obtenga un archivo PRE de gran tamaño. La utilidad collectcatkeys , que ya crea archivos CATKEYS legibles por humanos y fáciles de editar, funcionará con este archivo. Después de localizar las cadenas, debe usar la utilidad linkcatkeys .que agrega traducciones a los recursos del archivo ejecutable. Por lo tanto, cuando selecciona un idioma específico del sistema, la aplicación muestra las cadenas traducidas. Extraño, pero la documentación de la API de Haiku sobre la localización de aplicaciones contiene muy poca información. Sin embargo, en la web oficial encontré un excelente artículo Localizando una aplicación , que examinaba en detalle muchos aspectos de la traducción de aplicaciones para este sistema operativo. Según tengo entendido, en el BeOS original no había un marco de Locale Kit y se agregó solo en Haiku.

Mi siguiente paso fue elegir un entorno para desarrollar aplicaciones en el lenguaje de programación C++. Debido al hecho de que el marco Qt se ha portado a Haiku, los IDE como Qt Creator y están disponibles en el repositorio de HaikuPorts KDevelop . Además, hay un puerto JVM que le permite usar IDE escritos en el lenguaje de programación Java, como NetBeans o IntelliJ IDEA . Elegí el entorno de desarrollo Qt Creator, especialmente en sus últimas versiones hay un análisis cualitativo del código utilizando el analizador LibClang , que funciona en un orden de magnitud más preciso y rápido que el analizador estándar.


El entorno de desarrollo integrado Qt Creator que se ejecuta en el sistema operativo Haiku.

En términos del IDE conocido y multiplataforma en Haiku, todo está bien. Pero, ¿qué pasa con las soluciones exclusivas? No puedo dejar de mencionar un proyecto muy interesante, cuyo autor es DarkWyrm y que actualmente apoya a Adam Fowler , se llama Paladin . Este programa convierte el editor de texto Pe avanzado en la distribución del sistema operativo prácticamente en un IDE real.


Entorno de desarrollo integrado de Paladin para Haiku, instalado desde el repositorio de HaikuPorts.

Usando el mosaico integrado en el sistema de ventanas Haiku, puede adjuntar la ventana Paladin al costado del editor Pe y agregar una terminal. Incluso en el repositorio de HaikuPorts hay un conveniente editor de texto, Koder , que se asemeja al popular programa Notepad ++ para Windows y también se basa en los desarrollos del proyecto Scintilla . Creé un archivo PLD de proyecto para mi aplicación y ahora cualquier desarrollador que use Paladin IDE puede abrir mi proyecto en este programa sin ningún problema.

Cuando el entorno de desarrollo de Qt Creator estuvo configurado y listo para funcionar, comencé a implementar todas las características que había planeado. El primer problema que encontré estaba relacionado con la escala de los controles cuando se cambiaba el tamaño de la fuente del sistema. Inicialmente, en BeOS, todo el código de diseño de los elementos de la GUI se especificaba explícitamente en coordenadas. Era muy inconveniente, detallado y creaba una gran cantidad de problemas, por ejemplo, con el mismo cambio en el tamaño de fuente, todo el formulario de la aplicación se dispersó y quedó inutilizable. Afortunadamente, Haiku intentó resolver este problema y agregó la API de diseño , que forma parte del marco del kit de interfaz.


Mediante el uso de Layout API, los lanzadores responden correctamente al cambio del tamaño de la fuente del sistema en Haiku.

Esta innovación resolvió por completo mi problema con los controles de posicionamiento y reescribí la aplicación utilizando la API de diseño, lo que redujo considerablemente la longitud del código en algunos lugares. En el sitio web oficial de Haiku, encontré una serie de artículos interesantes, Laying It All Out , que solo explica las razones por las cuales se creó la interfaz de este programa y se muestran ejemplos de su uso.

Gerasim identificó un problema más, cuando intentó usar mi biblioteca para crear un lanzador para el juego, que portó. El punto era que a menudo recurría al código fuente del propio sistema operativo Haiku para implementar varias funcionalidades. En particular, encontré un ejemplo del uso del método Launch () en un objeto de la clase BRoster allí. El problema se manifestó en el hecho de que este ejemplo resultó ser incorrecto y el motor del juego, que fue portado por Gerasim, no pudo analizar correctamente los argumentos establecidos por el lanzador. Después de una mirada más cercana al código fuente de Haiku, logré descubrir que el primer argumento, que debe contener la ruta completa al archivo ejecutable, en el caso de Launch ()No es necesario especificar explícitamente el método, ya que se establecerá automáticamente.

// Errorconstchar* args[] = { "/bin/open", fURL.String(), NULL };
be_roster->Launch(&ref, 2, args);
// Goodconstchar* args[] = { fURL.String(), NULL };
be_roster->Launch(&ref, 1, args);
// See "src/kits/app/Roster.cpp", BRoster::ArgVector::Init() method:if (error == B_OK) {
    fArgs[0] = fAppPath.Path(); // <= Hereif (argc > 0 && args != NULL) {
        for (int i = 0; i < argc; i++)
            fArgs[i + 1] = args[i];
        if (hasDocArg)
            fArgs[fArgc - 1] = fDocPath.Path();
    }
    // NULL terminate (e.g. required by load_image())
    fArgs[fArgc] = NULL;
}

La documentación del método Launch () no dice nada sobre el hecho de que el primer argumento no es necesario, probablemente por eso el desarrollador escribió este código incorrectamente. Corregí este error en mi proyecto y el problema de Gerasim se solucionó solo. Pero, ¿qué pasa con este pequeño error en el propio sistema operativo Haiku? Decidí arreglarlo. ¡Afortunadamente, resultó ser muy fácil de hacer! Debe iniciar sesión con GitHub en el recurso Haiku Code Review Gerrit, agregar su clave SSH pública, bifurcar el código fuente de Haiku, crear una confirmación con la corrección y enviar el parche resultante a Code review a los desarrolladores privilegiados:

git clone ssh://EXL@git.haiku-os.org/haiku --depth=1 -b master && cd haiku
git commit
git push origin master:refs/for/master

Si necesita actualizar los parches ya enviados, antes de enviar confirmaciones modificadas o nuevas, debemos agregar al final del mensaje de confirmación la identificación que nos proporcionó el servicio de revisión de código Haiku. Después de enviar el parche, los desarrolladores de Haiku deben confirmarlo, rechazarlo o enviarlo para su revisión. En mi caso, la corrección se realizó de inmediato y este error menor ahora se eliminó en todas partes. Si necesita probar sus parches antes de enviarlos al repositorio, puede intentar usar la utilidad jam , que es una bifurcación del sistema de ensamblaje Perforce Jam y se usa para construir la base de código completa de Haiku, para compilar una aplicación separada. El repositorio de código fuente contiene el archivo ReadMe.Compiling.mdque te ayudará a lidiar con toda la sabiduría de la compilación.

Mientras finalizaba mi proyecto, encontré la razón por la cual Icon-O-Matic no abre archivos SVG creados con el editor de vectores Inkscape. El problema es que Icon-O-Matic no puede manejar el atributo viewBox , sin embargo, si encuentra un archivo SVG simple sin este atributo, edítelo con Inkscape y guárdelo como un archivo SVG simple , se abrirá en Icon-O-Matic . Por lo tanto, puse en mi repositorio un archivo SVG especialmente preparado que se puede editar y que se abrirá en Icon-O-Matic sin problemas. Además, agregué una pequeña instrucción al archivo Léame del proyecto sobre cómo crear íconos para mis lanzadores usando Inkscape.

Decidí verificar el código de mi proyecto con una variedad de analizadores estáticos, pero no encontraron ningún problema serio. Pero más tarde encontré un problema que no pudieron detectar. El hecho de que el método estático GetBitmap() clase BTranslationUtils podría devolver NULL:

// Somewhere
fBitmap = BTranslationUtils::GetBitmap(B_PNG_FORMAT, fIndex);
void
BeImageView::Draw(BRect rect)
{
    // Failconst BRect bitmapRect = fBitmap->Bounds();
    ...
}

Y en el método Draw () , sin darme cuenta olvidé verificar la validez del campo de la clase fBitmap . Por lo tanto, se esperaba que la aplicación cayera si no encontraba una imagen específica, pero de acuerdo con el plan, era necesario dibujar un cuadrado rojo en su lugar. Le conté esta historia al hecho de que los analizadores estáticos están lejos de ser una panacea y, en cualquier caso, se requiere cuidado cuando se trabaja con código en el lenguaje de programación C ++.

Subo el código fuente del proyecto BeGameLauncher y todo mi trabajo en el repositorio en GitHub. Espero que este programa sea útil para alguien y pueda convertirse en una especie de libro de texto como una aplicación simple para Haiku:

Código fuente del proyecto: https://github.com/EXL/BeGameLauncher

Un pequeño consejo para aquellos que usarán mi lanzador en sus recetas para el repositorio de HaikuPorts. Si quieres ocultar el archivo ejecutable del juego de la lista de aplicaciones Haiku que leen algunos programas, y dejar ahí solo el lanzador, puedes usar el siguiente truco:

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

Esto excluirá la posibilidad de iniciar archivos ejecutables sin los parámetros pasados ​​por el iniciador de varios programas como QuickLaunch , que se dedican al inicio rápido de aplicaciones. En este caso, se guardará su icono original en el archivo ejecutable.


6. Porting Xash3D: el mítico juego Half-Life y adiciones oficiales


El proyecto Xash3D es una implementación gratuita del motor GoldSrc, que se usa en el juego Half-Life y en sus adiciones oficiales. Detrás del desarrollo de Xash3D está el programador doméstico Uncle Misha , quien aún coordina su desarrollo y mejora. Un poco más tarde, otros desarrolladores se unieron al proyecto que bifurcó FWGS Xash3D , con el apoyo de una gran cantidad de sistemas operativos distintos de Windows. Hoy, los programadores clave del proyecto FWGS Xash3D son mittorn y a1batross ( libpony ), la última persona fue un participante activo en el otrora popular foro MotoFan.Ruque todavía administro en mi tiempo libre.

Me preguntaba: ¿por qué no portar este motor a Haiku, agregar soporte para un sistema operativo tan interesante al proyecto Xash3D, y dar a los usuarios de Haiku la oportunidad de jugar al legendario Half-Life, un juego de todos los tiempos y pueblos? El caso se quedó pequeño: era necesario comenzar de inmediato a trabajar en la portabilidad y, si tiene éxito, publicar los resultados de este trabajo.

Después de pasar varias horas estudiando la estructura del proyecto y aquellas partes del código que son responsables de soportar varias plataformas, comencé a hacer cambios en el motor Xash3D para que fuera posible soportar el sistema operativo Haiku. A la antigua, zafefilil el compilador -D__linux__e intenté compilar el ejecutable y un montón de bibliotecas. Sorprendentemente, las cosas fueron bastante rápido y por la noche, después de enviar los archivos de datos para el juego, logré ejecutar Half-Life y tomar un tren a la estación inicial en Black Mesa.


El proceso de portar el motor Xash3D a Haiku en el entorno de desarrollo integrado de Qt Creator.

Debido al hecho de que el proyecto utiliza la biblioteca multiplataforma SDL2, la migración del motor se simplifica enormemente, ya que no es necesario escribir ninguna pieza de código que dependa de la plataforma, por ejemplo: salida de sonido, creación de una ventana con contexto OpenGL o manejar eventos de entrada. Todo esto ya está implementado en la biblioteca SDL2 y listo para usar. Surgió un pequeño problema con el soporte de red, porque Haiku tiene una biblioteca separada que implementa la pila de red, respectivamente, se requería vincularla al motor.

El proyecto para crear lanzadores, sobre el cual escribí un poco más arriba, me resultó muy útil. Con la ayuda de la herencia de clase C ++, amplié seriamente su funcionalidad e implementé la capacidad de seleccionar varios complementos del juego:


Captura de pantalla del motor de lanzamiento de puertos Xash3D para Haiku.

La idea era la siguiente: determinar tres variables de entorno que permitieran la flexibilidad de personalizar el motor del juego para lanzar un complemento específico. Al mismo tiempo, sería útil dejar que el usuario juegue con los diversos argumentos del archivo ejecutable y dejar la posibilidad de que el motor se inicie de forma portátil cuando se encuentre en el directorio con los archivos de datos necesarios. Entonces, la primera variable de entorno XASH3D_BASEDIR es responsable del directorio con los archivos del juego que el usuario selecciona desde el lanzador. La segunda variable, XASH3D_GAME, es responsable de qué adición elige el usuario para iniciar en el lanzador. Y aquí está la tercera variable XASH3D_MIRRORDIR, útil solo para usuarios avanzados. Le permite duplicar el directorio del sistema Xash3D en cualquier espacio de usuario grabable en el disco. Por lo tanto, una persona que quiera lanzar su juego adicional en el motor Xash3D para Haiku necesita simplemente compilar varias bibliotecas dinámicas desde el código fuente de su proyecto para diferentes arquitecturas:

• ./cl_dlls/libclient-haiku.so
• ./ dlls/libserver-haiku .so •
./cl_dlls/libclient-haiku64.so
• ./dlls/libserver-haiku64.so

Y luego colóquelos en los directorios apropiados de su complemento. Para mi puerto Xash3D, decidí compilar previamente bibliotecas de complementos populares para el juego Half-Life, a saber, Blue Shift y Opposing Force ., que permitirá a los usuarios simplemente descargar sus archivos de datos, seleccionar un directorio e iniciar el juego sin compilar bibliotecas.

En el proceso de portar el motor Xash3D, encontré algunos problemas divertidos. Resulta que para determinar la longitud del mensaje de ayuda para los argumentos del archivo ejecutable, que se genera cuando se pasa el parámetro --help , el tamaño constante preestablecido MAX_SYSPATH , que es un alias de otro MAX_PATHconstante, cuyo valor se toma de la API de Haiku, se utilizó en el motor. Entonces, durante mucho tiempo no pude entender por qué este certificado se emite incompleto y se corta en el lugar más interesante. Al principio, pequé de que, de alguna manera extraña, el flujo de salida de error estándar stderr Buffering estaba conectado e incluso traté de forzarlo. Después de un tiempo, recordé que me sorprendió el tamaño tan pequeño de MAX_PATHconstante en el sistema operativo Haiku. Esta constante supone que el tamaño de la ruta es de solo 1024 bytes. Mi suposición se justificó por completo, tan pronto como aumenté el tamaño del mensaje a los 4096 bytes estándar, el problema se resolvió. Se debe sacar la siguiente conclusión de esta divertida historia: no debe usar la constante MAX_PATH en matrices de caracteres que no están relacionadas con las rutas de los archivos.


Un collage de capturas de pantalla del juego Half-Life, así como sus adiciones oficiales Blue Shift y Opposing Force, lanzadas usando el motor Xash3D en el sistema operativo Haiku (vista previa, aumento por referencia ).

Otro problema fue el bloqueo al usar la funcionalidad del propio motor para seleccionar el juego adicional. Resultó que cuando se configuró XASH_INTERNAL_GAMELIBS, la biblioteca del cliente se cargó no una, sino dos veces. Lo que llevó a un problema similar. Como me explicó a1batross , esto se hizo para poder vincular estáticamente el OpenVGUIbiblioteca a la biblioteca del cliente. En mi puerto Xash3D en Haiku, esta biblioteca no se usa en absoluto, así que dejé de usar los valores predeterminados XASH_INTERNAL_GAMELIBS y zeportil a los desarrolladores de este motor de errores.

A continuación, me encontré con la imposibilidad de abrir el navegador WebPositive integrado en Haiku cuando hacía clic en los enlaces dentro de un juego que se ejecutaba en Xash3D. Al mismo tiempo, el problema era realmente extraño, ya que el navegador se abría desde la terminal cuando se arrancaba el motor desde la terminal, pero cuando se lanzaba usando el lanzador, se negaba a hacerlo. Habiendo estudiado un poco el código, encontré una llamada execve () allí, que traté de reemplazar con system (), después de lo cual el navegador comenzó a abrirse sin ningún problema.

El motor Xash3D usa activamente llamadas de las funciones SDL_ShowSimpleMessageBox () y SDL_ShowMessageBox () cuando ocurren errores. , aquí solo el puerto actual de la biblioteca SDL2 para Haiku no admite la creación de estos diálogos. En nuestra versión de la biblioteca, esta funcionalidad simplemente falta. Pero hablaré sobre la corrección de este problema a continuación.


Motor Port Xash3D, publicado en el repositorio de Haiku Depot.

También vale la pena señalar que antes de transferir el motor Xash3D a Haiku, Gerasim Troyeglazov capturó el cursor del mouse en SDL2; Antes de eso, jugar juegos en 3D era casi imposible. Un poco más tarde, arregló un error ingenioso, en el que el movimiento de un jugador en el espacio se ralentizaba gradualmente y el juego comenzaba a ralentizarse terriblemente. Resulta que el punto era que por defecto los eventos del cursor del mouse se transmitían con todo su historial de movimiento en la pantalla. En consecuencia, esta historia se expandió rápidamente durante el juego y todo comenzó a ralentizarse. Deshabilitar esta característica en el puerto SDL2 en Haiku resolvió este problema y ahora puedes jugar en Half-Life sin ningún problema especial. Aunque la falta de aceleración 3D en una glándula débil se hace sentir. Y si el juego funciona decentemente en la ventana y no se ralentiza en absoluto,

Código fuente del proyecto: https://github.com/FWGS/xash3d

Envié todos los cambios en el código fuente a los desarrolladores del proyecto FWGS Xash3D, quienes los aceptaron en el repositorio, y los paquetes con este motor han estado disponibles durante mucho tiempo en HaikuPorts y en el programa Haiku para cualquier usuario de Haiku.

<< Saltar al contenido

7. Portando las dos partes del juego Serious Sam: The First Encounter y The Second Encounter


Recientemente, los desarrolladores de Croteam han publicado el código fuente de Serious Engine , que se utiliza en los juegos de la serie Serious Sam: The First Encounter y The Second Encounter . Decidí portarlo al sistema operativo Haiku, descargué el código fuente y comencé a trabajar.


Captura de pantalla del motor lanzador de puertos Serious Engine para Haiku.

El ensamblaje del archivo ejecutable después de los cambios realizados no ocurrió sin problemas, pero no fue tan fácil iniciar el juego debido al hecho de que llovían errores en los cuadros de diálogo SDL2, cuya implementación no está disponible en la versión. de esta biblioteca para Haiku. Por lo tanto, tuvimos que tomar el flujo estándar probado de salida de error stderr y comprender lentamente los problemas que se presentaban principalmente en ausencia de los archivos de datos del juego requeridos.


Captura de pantalla del juego Serious Sam: The Second Encounter, lanzado con el puerto del motor Serious Engine para el sistema operativo Haiku.

Después de descomponer los archivos descargados en los directorios requeridos, pude ejecutar la segunda parte de este maravilloso juego sin ningún problema e incluso corrí un poco por la hermosa jungla. A pesar de la falta de aceleración 3D, el procesador saca los encantos gráficos del juego, si lo ejecuta en una ventana y no en modo de pantalla completa. Este motor funciona, por supuesto, con un FPS más pequeño que el motor Xash3D, sobre el que escribí anteriormente, pero los gráficos aquí son más modernos y mejores. Después de algunas manipulaciones, fue posible iniciar la primera parte del juego, que requiere un archivo ejecutable diferente y un conjunto diferente de bibliotecas dinámicas. Sorprendentemente, ganó un poco más rápido, aparentemente los gráficos no son tan exigentes. Habiendo subido la configuración del motor,Encontré una gran cantidad de parámetros gráficos que pueden reducir significativamente la carga en el procesador,


Captura de pantalla del juego Serious Sam: The First Encounter lanzado con el puerto del motor Serious Engine para el sistema operativo Haiku.

Decidí hacer un paquete para dos partes del juego a la vez, el cambio entre ellas se hará simplemente seleccionando un directorio con el conjunto apropiado de archivos de datos. Por ejemplo, si un usuario elige un directorio con los archivos del juego Serious Sam: The First Encounter en el iniciador, se inicia el archivo ejecutable correspondiente y se carga el conjunto correspondiente de bibliotecas dinámicas. Y si elige el directorio con los archivos del juego Serious Sam: The Second Encounter, entonces el lanzador lanzará respectivamente otro archivo ejecutable, que cargará su propio conjunto de bibliotecas compartidas.

Desafortunadamente, no hubo problemas. Volver a cambiar la resolución del modo de video en el juego provocó la caída de todo el motor. Al mismo tiempo, en mi distribución de Linux, esta salida no fue así. Pasé mucho tiempo localizando el problema y arreglándolo. Resultó que todo era que cada vez que se cambiaba la resolución, la ventana SDL_Window se destruía y se volvía a crear ., mientras que el renderizador OpenGL no pudo cambiar a tiempo e intentó dibujar algo en la ventana destruida. Tales adornos de la biblioteca de puertos SDL2 en Haiku no permitían rotar. Todos los intentos simples de resolver este problema no ayudaron y tuve que entrar seriamente en la lógica y cambiar el comportamiento para que la ventana no colapsara cuando se cambiara la resolución, sino que simplemente cambiara sus parámetros. Esto ayudó a eliminar el bloqueo, pero agregó una limitación adicional: ahora, para activar el modo de pantalla completa, debe reiniciar el motor.

Otro problema fue la falta de música en el juego. Al mismo tiempo, en Linux, nuevamente, este problema no se manifestó. Explorando el código fuente del motor, descubrí que reproducir música depende de la biblioteca libvorbisfile, pero el motor en sí no se vincula a él, sino que usa la función del sistema dlopen () para enviar el flujo del archivo de audio OGG a esta biblioteca. El problema era que el motor no podía encontrar esta biblioteca en Haiku, ya que no había ningún enlace simbólico al archivo de la biblioteca sin la designación de la versión.

void CUnixDynamicLoader::DoOpen(constchar *lib)
{
    // Small HACK for Haiku OS (:#ifdef __HAIKU__staticint vorbis_cnt = 3;
    char path[PATH_MAX];
    char libpath[PATH_MAX];
    find_directory(B_SYSTEM_LIB_DIRECTORY, -1, false, libpath, PATH_MAX);
    if (strstr(lib, "vorbis")) {
        snprintf(path, sizeof(path), "%s/libvorbisfile.so.%c", libpath, char(vorbis_cnt + '0'));
        vorbis_cnt++;
        lib = path;
    }
#endif// fprintf(stderr, "dlopen => %s\n", lib);module = ::dlopen(lib, RTLD_LAZY | RTLD_GLOBAL);
    SetError();
}

El pequeño truco que colocó la ruta completa a la biblioteca requerida en la función resultó ser una solución bastante funcional. Y dado que el motor busca la biblioteca en su ausencia varias veces, dejé para el futuro la posibilidad de cargar la próxima versión principal. Espero que no rompan la API en él.

El siguiente problema que encontré fue la imposibilidad de determinar la frecuencia del procesador en la arquitectura x86, aunque en x86_64 todo funcionaba bien. Cuando se ejecuta en el motor x86, pedí establecer una variable de entorno llamada SERIOUS_MHZy establecer la frecuencia adecuada en él, lo que realmente me sorprendió. Traté de hacerlo y el juego realmente comenzó, pero por alguna razón funcionó demasiado lento. Habiendo escalado el código fuente del juego, no pude encontrar la fuente del problema durante mucho tiempo e incluso escribí un código que, usando la API de Haiku, obtiene la frecuencia correcta del procesador y la inserta en el motor del juego, esto es como se veía:

#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);

Pero no ayudó. Luego revisé los registros del motor en x86_64 y vi que la frecuencia de la CPU generalmente se define en 1 MHz, pero todo funciona bien. Continuando con la exploración del código, me topé con la denegación de __GNU_INLINE_X86_32__ define , que se configura automáticamente cuando la aplicación se crea para la arquitectura x86, pero no para x86_64. Debajo de esta definición, la casilla de verificación que le decía que usara los temporizadores SDL2 se escondió en lugar de obtener la frecuencia del procesador usando varias instrucciones mágicas como ensamblador en línea y rdtsc o leyendo el archivo /proc/cpuinfo , así que me aseguré de que este indicador estuviera activado y para x86, eso resolvió mi problema.

El último defecto estaba relacionado con mi descuido. Eché de menos en el archivo de compilación CMakeLists.txt la instalación de la bandera -march = native , que literalmente le habla al compilador: al generar bloques de código de máquina, use todas las instrucciones avanzadas y modernas que están disponibles en el procesador de su computadora.

if(NOT PANDORA ANDNOT HAIKU)
    message("Warning: arch-native will be used!")
    add_compile_options(-march=native)
endif()
if(HAIKU)
    if(CMAKE_SIZEOF_VOID_P EQUAL4) # 32-bitmessage("Warning: Will building 32-bit executable with MMX, SSE, SSE2 support.")
        add_compile_options(-mmmx -msse -msse2)
    else()                          # 64-bitmessage("Warning: Will building 64-bit executable.")
    endif()
endif()

Debido a esto, los paquetes en el repositorio se reunieron exclusivamente para el servidor de compilación más poderoso y se negaron a ejecutarse en las computadoras de las personas mortales comunes, maldiciendo las instrucciones y los códigos de operación incorrectos. Deshabilitar este indicador y agregar manualmente soporte para las instrucciones MMX, SSE y SSE2 no solo resolvió este problema, sino que también permitió compilar una gran cantidad de ensamblador en línea en este proyecto, que cayó después de que se eliminó este indicador.

Para mi gran pesar, los desarrolladores de Croteam no aceptan ningún parche en el repositorio del motor, así que hice un fork y puse todo mi trabajo ahí:

Código fuente del proyecto: https://github.com/EXLMOTODEV/Serious-Engine

Los paquetes listos para instalar que le permiten iniciar los juegos de Serious Sam ya están disponibles en el repositorio de HaikuPorts. Solo recuerda descargar los archivos de datos del juego.


8. Portando el juego Vangers


Francamente, hasta hace poco, no estaba completamente familiarizado con este juego, que en los lejanos años 90 hizo el estudio de desarrollo nacional KD Lab. Pero los participantes de la conferencia en Telegram IM , que está dedicada a una discusión sobre el sistema operativo Haiku, me pidieron que portara a Wangers y me dieron un enlace al repositorio de GitHub , que contenía las fuentes de este juego.


Captura de pantalla del juego de lanzamiento de puerto Wangers para Haiku.

Metiendo el código fuente en Haiku, traté de compilarlos y lo hice sin ningún problema especial. Poco hubo que trastear con la falta de algunos archivos de cabecera y las rutas a las bibliotecas FFmpeg , que son las que utiliza el motor de este juego. Inmediatamente comencé a preparar el código fuente para el empaquetado, así que agregué la variable de entorno VANGERS_DATA y transfirí el registro del motor al directorio de usuarios disponible para escritura.


El proceso de migrar el juego Wangers a Haiku en el entorno de desarrollo integrado de Qt Creator.

Lancé el juego y después de un tiempo aprecié toda la atmósfera que los muchachos de KD Lab lograron crear. Después de un tiempo, comencé a llevar alegremente el Nimbus a la incubadora y la flema al Podish, después de lo cual incluso logré llevar el Elika al tercero. Habiendo jugado lo suficiente, comencé a preparar un iniciador para este juego basado en mi biblioteca, sobre la cual escribí anteriormente.


El puerto del juego Wangers que se ejecuta en el sistema operativo Haiku.

El primer problema que encontré fue que los archivos de datos del juego que podían obtenerse oficialmente mediante los servicios de distribución digital GOG.com y Steam no querían funcionar con el motor. Tuve que contactar a una persona que usa el apodo de stalkerg y que se dedicaba a portar Wangers a Linux. Me dijo qué archivos deben cambiarse para que todo comience y comience a funcionar. Seguí sus recomendaciones y obtuve lo que necesitaba.

Como en el caso del puerto NXEngine (Cave Story), sobre el cual escribí anteriormente, las versiones en ruso e inglés se diferencian entre sí por diferentes archivos ejecutables, pero el directorio con los archivos de datos es común, las diferencias están solo en los scripts . En el aviso de stalkerg, traté de compilar el motor del juego con la opción -DBINARY_SCRIPT = Off, que activó la compilación dinámica de estos scripts durante la ejecución, si están disponibles en el directorio de archivos de datos del juego. Todo esto me permitió crear un lanzador, en el que existe la posibilidad de cambiar el idioma. La idea es la siguiente: el directorio del juego se verifica preliminarmente y, si no contiene los scripts necesarios, se copian de los componentes internos del paquete, después de lo cual se inicia el archivo ejecutable de la versión rusa o inglesa.


El puerto del juego Wangers, publicado en el repositorio de Haiku Depot.

Al portar Wangers, utilicé una característica interesante relacionada con las bibliotecas compartidas, que me gusta en Haiku. El motor del juego depende de la biblioteca dinámica libclunk.so , que se encarga de generar sonidos binaurales en tiempo real. Y si en Linux me tengo que romper los dedos, sustituyendo la ruta de esta librería en la variable de entorno LD_LIBRARY_PATH , para que también se haya guardado lo que había en esta variable, entonces Haiku lo ha hecho cómodamente, como en Windows. Basta con colocar la biblioteca compartida al lado del archivo ejecutable y se recogerá, con la única diferencia de que en el caso de Haiku la biblioteca debe colocarse en el ./lib/directorio Eso, en mi opinión, permite ahorrar mucho tiempo y nervios. Por lo tanto, decidí no considerar una compilación estática de esta biblioteca.

Código fuente del proyecto: https://github.com/KranX/Vangers

Los desarrolladores de Wangers aceptaron mis cambios en su motor de juego y los paquetes listos para instalar están disponibles para descargar desde el repositorio de HaikuPorts o el programa HaikuDepot, a pesar de la corrección reciente en la infraestructura del repositorio que sucedió después de actualizar la distribución Linux de Fedora a la nueva versión.

<< Saltar al contenido

9. Implementación de diálogos en la biblioteca SDL2 para Haiku


Al portar los motores Xash3D y Serious Engine, sobre los cuales escribí anteriormente, me topé con el puerto local de la biblioteca SDL2 por la falta total de implementación de diálogo. Los diálogos son llamados por dos funciones SDL_ShowSimpleMessageBox () y SDL_ShowMessageBox () , que le permiten informar al usuario sobre cualquier información importante, como un error. La implementación de estos diálogos está disponible en muchas plataformas y sistemas operativos: Windows, macOS, iOS, X11 y Android, pero por alguna razón no se encuentran en Haiku. Decidí corregir esta omisión y agregar esta funcionalidad al puerto de la biblioteca SDL2.

En la API de Haiku, o más bien en el marco del kit de interfaz, hay una excelente Clase BAlert . lo cual es excelente para implementar tales diálogos. Decidí elegirlo como base. Lo único que me confundió fue que no estaba seguro de que se pudieran colocar más de tres botones en el cuadro de diálogo que construye BAlert . También recordé las funciones de administración de memoria en esta clase sobre las que escribí anteriormente: puede crear sus objetos solo en el montón, y no puede crearlos en la pila, porque después de llamar al método Go () y la acción del usuario posterior, se borra a sí mismo. Habiendo realizado algunos experimentos, disipé todas mis dudas, heredé de esta clase y comencé a escribir una implementación.


La implementación de los diálogos en la librería SDL2 para el sistema operativo Haiku.

La primera dificultad que encontré fue que al usar cualquier objeto de la clase BAlert o sus herederos, era necesario crear una instancia de la clase del sistema BApplication , aparentemente, para registrar la aplicación en app_server para poder interactuar con ella. Creé una instancia de esta clase, pero cuando llamé al diálogo BAlert desde otro proceso o desde la ventana creada, recibí otro error relacionado con el hecho de que la aplicación no podía tener dos objetos de BApplication.class , afortunadamente encontré una solución a este problema. La API de Haiku tiene un puntero global a la instancia actual de la clase. BApplication , que se llama be_app , su contraparte en el marco Qt es una macro qApp especial , que también define un puntero al objeto de la aplicación actual. Por lo tanto, basta con verificar el puntero be_app a NULL y, si la verificación se completa con éxito, cree el objeto requerido. Por lo tanto, todos estos problemas fueron resueltos.

Vale la pena señalar que la biblioteca SDL2 está escrita en el lenguaje de programación C, y se sabe que la API de Haiku usa el lenguaje de programación C ++. Debido a esto, algunas partes del código siempre deben mancharse con acuerdos vinculantes externos "C" para que no haya problemas con la resolución de caracteres durante el proceso de vinculación. Además, en lugar de nuevo , debe usar el operador nuevo (std :: nothrow) para poder verificar la memoria asignada por NULL, en lugar de lanzar una excepción, que SDL2, por supuesto, no admite.

Por lo demás, no había nada complicado. Escribimos varias funciones que convierten entidades y representaciones SDL2 de tal manera que sean compatibles con la API de Haiku y verifiquen su correcto funcionamiento. Para varios controles, extendí una pequeña prueba.que ocasionalmente ejecuté en diferentes sistemas operativos, analicé los resultados y evalué mi trabajo. Al final, me dejé llevar tanto que incluso hice un soporte de personalización, como configurar diferentes colores para los botones y el fondo del diálogo. Esto es compatible con la API de la biblioteca SDL2, pero inicialmente no planeé implementar tales cosas.

Si el programador decide escupir una línea muy, muy larga en este cuadro de diálogo, entonces el objeto de clase BTextView que se usa dentro del objeto de clase BAlert debe llamar al método SetWordWrap () con un verdaderoargumento para golpear al programador en sus manos y hacer que el diálogo quepa en la pantalla. Parecería que nada es más simple: verificamos la longitud de la cadena con la ayuda de la función strlen () y hacemos lo correcto. El problema es que SDL2 funciona igual con UTF-8, lo que significa que la función strlen() devolverá la cantidad de bytes, no la cantidad de caracteres. Haiku API viene al rescate y la clase de cadena BString contiene el método CountChars () , que le permite averiguar la longitud de una cadena en caracteres, no en bytes:

boolCheckLongLines(constchar *aMessage){
    int final = 0;
    // This UTF-8 friendly. P.S. G_MAX_STRING_LENGTH = 120
    BString message = aMessage;
    int32 length = message.CountChars();
    for (int i = 0, c = 0; i < length; ++i)
    {
        c++;
        if (*(message.CharAt(i)) == '\n')
        {
            c = 0;
        }
        if (c > final)
        {
            final = c;
        }
    }
    return (final > G_MAX_STRING_LENGTH);
}

Esta función verifica el texto del mensaje en busca de líneas de más de 120 caracteres y, si hay alguna, devuelve verdadero. En cuanto a UTF-8, todavía hubo un momento en que algunas de las fuentes del sistema Haiku carecen de soporte para caracteres chinos. Por lo tanto, por ejemplo, es imposible instalar ninguna inscripción en chino en el título de la ventana. Pero el texto en ruso se instala sin problemas.

Al preparar el paquete, encontré un error de ensamblaje para la arquitectura x86_gcc2, que se activa en la receta de la biblioteca SDL2. Resultó que el compilador GCC 2.95 más antiguo no puede adivinar que el código comentado es equivalente al siguiente:

rgb_color ConvertColorType(const SDL_MessageBoxColor *aColor)const{
    // return { aColor->r, aColor->g, aColor->b, 255 };
    rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 };
    return color;
}

Así que tuve que reescribir este fragmento en el estilo antiguo y aún eliminar la inicialización de algunas constantes en la clase directamente en sus declaraciones, al antiguo compilador tampoco le gustó.

Envié parches para la implementación de los diálogos de SDL2 al repositorio de HaikuPorts, para que ahora los motores Xash3D y Serious Engine puedan brindar correctamente al usuario cualquier información, por ejemplo, sobre errores. Pero aún no me he puesto en contacto con los desarrolladores de SDL2, pero sería bueno transferir todos los parches desde el repositorio de HaikuPorts a la biblioteca SDL2 ascendente. Aunque el trabajo de transferir nuestros parches se ha vuelto un poco más complicado debido al reciente cambio de nombre de los prefijos de función de BE_ * a HAIKU_ *, pero esto no es un problema tan grave.


10. Portando mi fork al programa Cool Reader


He estado desarrollando el programa Cool Reader durante mucho tiempo, que fue escrito por Vadim Lopatin ( Buggins ), el artículo correspondiente sobre esto está disponible en mi sitio. En los comentarios a este artículo, los lectores de mi blog se dan de baja constantemente, que quieren ver alguna característica nueva en su aplicación de lectura de libros electrónicos favorita o quieren corregir errores y deficiencias en las funciones ya implementadas del programa.


My fork es un programa Cool Reader que se ejecuta en el sistema operativo Haiku.

En el repositorio de HaikuPorts, encontré una receta para construir el programa Cool Reader original, pero debido a algunos cambios constantes con SourceForge , esta receta no funcionaba porque el código fuente de la aplicación ya no estaba disponible para descargar. Entonces decidí mover mi bifurcación al repositorio de HaikuPorts, como una nueva versión de Cool Reader. Puse todos los parches de Gerasim en el código, corregí algunas de las deficiencias en la receta y, en base a esto, creé un nuevo paquete que ya está disponible para todos los usuarios de Haiku. El código fuente de mi bifurcación Cool Reader se puede encontrar en este repositorio de GitHub:

Código fuente del proyecto: https://github.com/EXLMOTODEV/coolreader

El único problema que encontré fue la imprecisión de transferir los parches de Gerasim. Además de definir __HAIKU__ , en algún lugar del sistema de compilación, también se expuso la definición de _LINUX y, dado que en la mayoría de los casos el último en la lista del código fuente era el primero, la compilación condicional me defraudó. De acuerdo con las reglas de prioridad del preprocesador, Haiku compiló exactamente aquellas piezas de código que estaban enmarcadas con _LINUX , aunque necesitaba algo completamente diferente. Pero incluso a pesar de esto, el programa comenzó y funcionó, solo que guardó su configuración en el lugar equivocado. Prioricé correctamente, reconstruí el paquete y el problema se resolvió por completo.

<< Saltar al contenido

11. Mejora del programa KeymapSwitcher


Recientemente, muchos sistemas operativos populares han cambiado al nuevo atajo de teclado Meta / Opt / Cmd / Win + Space para cambiar el diseño del teclado. Me pareció muy conveniente porque ahora no hay necesidad de cambiar nada y ajustar. Te sientas en cualquier computadora que ejecute macOS, Windows o Linux con el shell GNOME 3 y esta conveniente combinación de cambiar el idioma de entrada funciona en todas partes. Incluso en el sistema operativo móvil Android tiene su contraparte. En general, cambié por completo a esta combinación de teclado hace mucho tiempo y me acostumbré mucho.

Muy a mi pesar, el programa KeymapSwitcher, que viene con Haiku, no permitía configurar un atajo de teclado tan conveniente para cambiar de diseño, por lo que constantemente me sentía incómodo trabajando con texto en este sistema operativo. Por lo tanto, decidí modificar un poco esta aplicación y comencé a buscar su código fuente. Resultó que este programa, aunque incluido en la distribución de Haiku, se suministra por separado del código fuente del propio sistema operativo. Además, la aplicación está disponible en el repositorio de HaikuPorts y también se actualiza a través de él. Como me informaron, KeymapSwitcher no se incluyó en Haiku, porque está planeado implementar una API especial para cambiar la distribución del teclado y, en algún momento, la necesidad de este programa desaparecerá por completo.


El programa KeymapSwitcher en el sistema operativo Haiku con la popular combinación de teclas para cambiar el diseño del teclado.

A pesar de que estaba asustado por la complejidad del código KeymapSwitcher, rápidamente encontré el lugar correcto gracias a los comentarios e introduje un pequeño parche en el código del programa, lo que facilitó enormemente la escritura de cualquier texto en Haiku. El único defecto menor que no pude superar es que se debe soltar la tecla Opt para cambiar el idioma. Es decir, abrazadera Opty el cambio de espacio entre los idiomas seleccionados no funcionará. Pero no interfiere en absoluto con el cambio de idioma durante la escritura, así que envié el parche al repositorio del programa y actualicé el paquete de la aplicación en HaikuPorts, después de lo cual la nueva versión de KeymapSwitcher estuvo disponible para su instalación para todos los usuarios de Haiku.

Código fuente del proyecto: https://github.com/HaikuArchives/KeymapSwitcher

Espero no ser el único usuario de este método abreviado de teclado para cambiar la distribución del teclado.


12. Conclusión


Estudiar la API de Haiku, así como resolver varios problemas exóticos que surgieron como resultado de la migración de aplicaciones nuevas y el perfeccionamiento de aplicaciones existentes para este sistema operativo, me brindó una enorme cantidad de valiosa experiencia y placer. Pude promocionar los parches de soporte de haiku en el repositorio de código fuente de algunos proyectos grandes y conocí a nuevas personas interesantes que de alguna manera estaban conectadas con este maravilloso sistema operativo.


Varias aplicaciones que se ejecutan en el sistema operativo Haiku.

Espero sinceramente que en el futuro todos los problemas actuales, como la falta de aceleración de hardware 3D y los navegadores populares, así como el soporte deficiente para el hardware moderno, se resuelvan con éxito y Haiku reciba una afluencia de nuevos desarrolladores y usuarios que apreciarán su Características únicas y diseño original. Afortunadamente, el desarrollo está lejos de estar en su lugar y hoy en día se plantean temas candentes sobre la aceleración 3D y la migración de la biblioteca GTK + 3 en el foro local de este sistema operativo, y la posibilidad de transferir el componente QtWebEngine se discute en los repositorios de HaikuPorts .. El puerto GTK+ 3 puede llevar al lanzamiento y funcionamiento de los populares navegadores Firefox y Chromium, y QtWebEngine permitirá usar el motor Blink en navegadores modernos basados ​​en el framework Qt, como Otter Browser o Falkon .

Ya puedo recomendar este sistema operativo a aquellos que tienen computadoras portátiles o netbooks viejas y débiles, por ejemplo, en lugar del kit de distribución de Lubuntu o Windows XP. Te sorprenderá lo rápido y receptivo que funciona. Sí, tendrá que limitarse un poco a navegar por algunos sitios debido a los navegadores antiguos y muchos problemas técnicos asociados con ellos, pero en la mayoría de los casos, esta restricción no es un problema importante en el hardware antiguo.

Todos mis puertos y mejoras ya se han publicado y están disponibles para su instalación para todos los usuarios de Haiku. Todos los cambios al código fuente están disponibles en los repositorios correspondientes bajo sus licencias originales. En este trabajo, utilicé una gran cantidad de materiales, los principales los destacaré en los enlaces útiles a continuación. Muchas gracias a los recursos stackoverflow.com y google.com por el hecho de que lo son.

1. El sitio web oficial del sistema operativo Haiku .
2. El sistema operativo oficial del foro Haiku .
3. Documentación oficial para usuarios de Haiku .
4. Documentación oficial para desarrolladores de Haiku .
5. Descripción de las funciones de la GUI de Haiku .
6. Recomendaciones para la creación de iconos para aplicaciones Haiku .
7. Descripción del programa Icon-O-Matic y consejos para su uso .
8. Descripción del formato de iconos vectoriales HVIF .
9. Documentación oficial para el marco del kit de interfaz .
10. Documentación del marco del kit de configuración regional oficial .
11. Un artículo sobre localización de aplicaciones para Haiku .
12. Documentación oficial sobre la interfaz de software Layout API .
13. Una serie de artículos que hablan sobre la introducción de la interfaz API de diseño para Haiku.
14. Código fuente del repositorio GitHub del sistema operativo Haiku .
15. GitHub-repositorio del árbol de recetas de HaikuPorts .
16. Versión de Internet del repositorio de paquetes HPKG listos para usar de Haiku Depot Web .
17. Un artículo interesante "Haiku: Lamp geek-OS" en el blog del desarrollador INSTEAD, Peter Kosykh .
18. Artículo "Haiku: inmersión" en el blog del desarrollador INSTEAD, Peter Kosykh .
19. El curso de programación DarkWyrm Aprendiendo a programar con Haiku .
20. El curso de lecciones de programación “Programación con Haiku” de DarkWyrm .
21. La publicación “¿Hay vida en Haiku?” En Linux.org.ru, de mí .
22. Conferencia en Telegram IM, dedicada a la discusión del sistema operativo Haiku .

¡ Felicitaciones a todos los usuarios del recurso habr Feliz Año Nuevo y les deseo feliz Navidad! ¡Buena suerte a ustedes en el nuevo año 2019!
Hora de Libertad

Post a Comment

Previous Post Next Post