1509 lines
94 KiB
Text
1509 lines
94 KiB
Text
= Manual de Singe
|
|
Scott Duensing <scott@kangaroopunch.com>
|
|
:revnumber: 3.00
|
|
:revdate: 2026
|
|
:doctype: book
|
|
:toc: left
|
|
:toclevels: 3
|
|
:sectnums:
|
|
:sectnumlevels: 3
|
|
:title-logo-image: image:images/singeLogo.png[Singe, pdfwidth=2.6in, align=center]
|
|
:source-highlighter: rouge
|
|
:icons: font
|
|
:experimental:
|
|
:lang: es
|
|
:imagesdir: ..
|
|
include::locale.adoc[]
|
|
|
|
[#_about_singe]
|
|
== Acerca de Singe
|
|
|
|
Singe (Scott's Increasingly Nifty Game Engine, «el motor de juegos cada vez más
|
|
ingenioso de Scott», que debe su nombre al dragón de Dragon's Lair) es un
|
|
sistema de scripts basado en Lua que permite crear rápidamente prototipos de
|
|
nuevos juegos de laserdisc, o crear juegos totalmente nuevos. El lenguaje es
|
|
fácil de aprender, muy potente y rápido. Todo lo necesario para desarrollar tu
|
|
propio juego está disponible a través de una sencilla interfaz de programación
|
|
de aplicaciones (API).
|
|
|
|
Singe ofrece numerosas funciones al desarrollador de juegos. Algunas de las más
|
|
interesantes son:
|
|
|
|
* Escenas 3D con modelos, animación, iluminación y sombras
|
|
* Física, con articulaciones, ragdolls, cuerpos blandos y vehículos
|
|
* Menús, pantallas de opciones y HUD construidos como páginas web
|
|
* Decodificación de vídeo por hardware, incluso en máquinas pequeñas
|
|
* Récords en línea y un catálogo de juegos para descargar y actualizar
|
|
* Juegos empaquetados en un solo archivo
|
|
* Lenguaje de programación orientado a objetos
|
|
* Sprites animados
|
|
* Compatibilidad con fuentes TrueType
|
|
* Espacio de color de 32 bits con transparencia
|
|
* Sonido estéreo multicanal y superpuesto, y MIDI
|
|
* Compatibilidad con dispositivos de entrada analógicos y digitales, incluidas las pistolas de luz
|
|
* Amplia compatibilidad con formatos de vídeo y audio
|
|
|
|
Singe funciona en Windows, macOS y Linux, con procesadores ARM además de Intel y
|
|
AMD: portátiles con Windows en ARM, la Raspberry Pi y consolas portátiles como la
|
|
R36S.
|
|
|
|
Para los jugadores, Singe permite disfrutar de muchos juegos nuevos y no
|
|
emulados con el front-end que prefieras o con el sistema de menús incluido.
|
|
|
|
Desde el lanzamiento original de Singe allá por 2006, se han publicado varias
|
|
revisiones, tanto oficiales como no oficiales. En 2020 se publicó Singe 2.00.
|
|
Era una reescritura total desde cero, que añadía numerosas funciones sin dejar
|
|
de ser compatible con los juegos 1.xx existentes. Singe 3.00 añade 3D, física,
|
|
interfaces de usuario y mucho más, y sigue ejecutando los juegos que vinieron
|
|
antes. En el momento de escribir este manual, la última versión es la
|
|
{revnumber}.
|
|
|
|
[#_installation_and_upgrading]
|
|
== Instalación y actualización
|
|
|
|
[#_installing_singe]
|
|
=== Instalar Singe
|
|
|
|
Para instalar Singe, basta con descargar el binario adecuado para tu sistema.
|
|
Ponlo solo en una carpeta nueva y ejecútalo. La primera vez que se ejecuta,
|
|
Singe crea todas las carpetas y archivos de soporte necesarios. Ya puedes
|
|
instalar algunos juegos. En un PC con Windows y procesador ARM, elige la versión `Windows-aarch64`: la
|
|
versión `Windows-x86_64` también funciona allí, emulada, pero más despacio.
|
|
|
|
[#_upgrading_singe]
|
|
=== Actualizar Singe
|
|
|
|
Para actualizar Singe a una versión más reciente, pon el binario nuevo en la
|
|
carpeta de instalación junto al antiguo y ejecútalo una vez con `--refresh`. La
|
|
carpeta de soporte que haya se aparta como `old-Singe-<version>`, con el nombre
|
|
de la versión que la escribió, y en su lugar se escribe una carpeta `Singe/`
|
|
nueva. No se borra nada: la carpeta apartada es tuya, para conservarla o
|
|
quitarla, y un segundo `--refresh` aparta la suya como `old-Singe-<version>-1`
|
|
en lugar de escribir encima de la primera.
|
|
|
|
El binario antiguo puede quedarse donde está. `Menu.sh` (o `Menu.bat`) ejecuta
|
|
el Singe más reciente que encuentra junto a sí mismo, y una beta cuenta como más
|
|
antigua que la versión final del mismo número, así que `Singe-v3.00b2` cede el
|
|
paso a `Singe-v3.00` en cuanto este llega. La herramienta Engine Update del menú
|
|
hace todo esto por ti; véase <<servicetools,Las herramientas de servicio>>.
|
|
|
|
WARNING: No ejecutes un binario nuevo de Singe con un conjunto de archivos de
|
|
soporte desactualizado. Renueva siempre la carpeta `Singe/` al actualizar.
|
|
|
|
[#_things_to_know]
|
|
=== Cosas que debes saber
|
|
|
|
No toques la carpeta `Singe/`. Los archivos de esta carpeta pertenecen a Singe y
|
|
pueden actualizarse o borrarse en cualquier momento.
|
|
|
|
[#_playing_games]
|
|
== Jugar
|
|
|
|
[#_installing_games]
|
|
=== Instalar juegos
|
|
|
|
Un juego es o bien un único archivo `.game` o bien una carpeta. Cópialo en la
|
|
misma carpeta en la que pusiste el binario de Singe. El sistema de menús
|
|
incluido lo detectará automáticamente y lo añadirá al menú.
|
|
|
|
[#_game_directory_layout]
|
|
=== Estructura de la carpeta de juegos
|
|
|
|
Una instalación de Singe es una carpeta de juegos que contiene la carpeta de
|
|
soporte `Singe` que el motor crea en la primera ejecución, una carpeta por
|
|
juego, los archivos `.game` empaquetados que haya y una carpeta `data` para
|
|
todo lo que escriben los juegos y el motor. El ejecutable suele estar ahí
|
|
también, pero no hace falta: `--gamedir` indica la carpeta de juegos desde
|
|
cualquier sitio, y el `Menu.sh` (o `Menu.bat`) que el motor escribe ahí ejecuta
|
|
entonces el ejecutable por su ruta completa. Si no, el lanzador busca junto a sí
|
|
mismo los archivos cuyos nombres empiezan por `Singe` y ejecuta el mejor de
|
|
ellos, al estilo de los lanzadores que escribe `BatMaker`, de modo que una
|
|
actualización que cambia la versión en el nombre del ejecutable no deja un
|
|
lanzador apuntando a un archivo que ya no está.
|
|
|
|
El mejor significa primero la arquitectura de esta máquina y después la versión.
|
|
La plataforma del nombre se compara con lo que informa el sistema, porque una
|
|
compilación más reciente para otra arquitectura no puede ejecutarse en absoluto,
|
|
y una misma carpeta de juegos en un recurso compartido puede leerla tanto una
|
|
Pi como un PC. El lanzador lo averigua cada vez que se ejecuta en lugar de que se
|
|
lo digan una sola vez, así que la misma carpeta sirve para todas las máquinas
|
|
que la abren. En un Mac, una compilación universal cuenta como nativa. Entre las
|
|
compilaciones que esta máquina puede ejecutar, gana la más reciente:
|
|
`Singe-v3.10` gana a `Singe-v3.09`, y una beta pierde frente a la versión final
|
|
a la que precede, así que `Singe-v3.00b2` pierde frente a `Singe-v3.00`. Una
|
|
compilación para otra arquitectura se ejecuta igualmente cuando es la única que
|
|
hay, ya que una queja real del motor es mejor que oír que no se encontró nada, y
|
|
lo mismo pasa con un nombre que el lanzador no consigue leer en absoluto.
|
|
|
|
----
|
|
Singe/ Archivos de soporte extraídos por el motor
|
|
Framework.singe Lo carga cada juego (con dofile)
|
|
Menu.singe El menú de juegos incluido
|
|
Tools.singe Las herramientas de servicio del menú (véase Las herramientas de servicio)
|
|
MenuDocument.singe El menú dibujado como documento de la GUI
|
|
MenuOverlay.singe El menú dibujado en el overlay, para una máquina sin GPU
|
|
Backdrop.singe La intro del menú y la cuadrícula de detrás, dibujadas en directo
|
|
menuBackground.mkv El mismo fondo grabado, para una máquina sin GPU
|
|
menuIntro.flac Su sonido, que se desvanece cuando el menú ocupa la pantalla
|
|
Menu.rml El documento RmlUi del renderizador de documentos
|
|
menu.rcss Su hoja de estilo, por encima de gui.rcss
|
|
gui.rcss El tema de la GUI incluido
|
|
controls.cfg.example Plantilla para las asignaciones de entrada
|
|
click.wav Lo usan las pruebas de retardo de audio y de sonido del menú
|
|
Manual.pdf Este manual
|
|
Manual-fr.pdf Este manual en francés
|
|
Manual-it.pdf Este manual en italiano
|
|
Manual-de.pdf Este manual en alemán
|
|
Manual-es.pdf Este manual en español
|
|
COPYING La Licencia Pública General de GNU, versión 3
|
|
LICENSES Avisos de terceros y créditos de los recursos
|
|
Collection/ Una carpeta de juegos
|
|
games.dat Entradas del menú para los juegos de esta carpeta
|
|
AsteroidPatrol.singe Un script
|
|
frame_AsteroidPatrol.txt Su framefile (o un vídeo con el mismo nombre base)
|
|
sprite_*.png, sound_*.wav, font_*.ttf
|
|
MyGame.game Un juego empaquetado en un solo archivo (véase Juegos en un solo archivo)
|
|
data/
|
|
machine.cfg El retardo de audio y la geometría de imagen de esta máquina
|
|
Collection/ Índices, trace.txt, capturas de pantalla y partidas guardadas de esos juegos
|
|
----
|
|
|
|
Dónde busca Singe los archivos de un script, y dónde puede escribir un script,
|
|
es asunto de quien escribe el script; la Referencia de Singe trata las dos
|
|
cosas en «Empaquetar tu juego».
|
|
|
|
[#bundledmenu]
|
|
=== El menú incluido
|
|
|
|
`Menu.sh` (o `Menu.bat`) inicia `Singe/Menu.singe`, el menú incluido: un
|
|
documento RmlUi, `Singe/Menu.rml` con el estilo de `Singe/menu.rcss`, dibujado
|
|
sobre un fondo 3D en directo (véase xref:Reference.adoc#gui[GUI]). El menú
|
|
funciona sin disco; una máquina sin GPU reproduce en su lugar
|
|
`Singe/menuBackground.mkv`, una grabación del mismo fondo, detrás de una página
|
|
más sencilla dibujada en el overlay. Lee el `games.dat` de cada carpeta de
|
|
juego y de cada archivo `.game` que tiene al lado y muestra todos los juegos que
|
|
encuentra, ordenados por título, a lo largo del lado izquierdo de la pantalla.
|
|
Junto a la lista están el arte de la recreativa del juego seleccionado, su
|
|
marquesina y su clip del modo de atracción, con el año, el género, la
|
|
plataforma, el desarrollador, el editor, los créditos de la conversión y la
|
|
descripción debajo, y una línea de indicaciones de teclas en la parte inferior.
|
|
|
|
Arriba y abajo mueven la selección de juego en juego, e izquierda y derecha la
|
|
mueven de página en página; ambas dan la vuelta de un extremo de la lista al
|
|
otro. Start o cualquier botón de acción inicia el juego seleccionado, y la tecla
|
|
asignada a `INPUT_SERVICE` (la tecla `9` por defecto) abre las herramientas de
|
|
servicio (véase <<servicetools,Las herramientas de servicio>>). Con un ratón, un
|
|
clic en una fila selecciona ese juego y un segundo clic en la misma fila lo
|
|
inicia; la rueda del ratón desplaza una descripción demasiado larga para su
|
|
panel. Si configuras `--quitchord`, mantener pulsados esos botones te saca de un
|
|
juego al menú, y del menú a tu sistema (véase <<handhelds,Consolas portátiles y
|
|
máquinas pequeñas>>). El menú guarda su selección en `menu.dat` en su carpeta
|
|
de datos, así que vuelve al mismo juego cuando sales de uno o la próxima vez que
|
|
se inicia Singe. Ese archivo es un fragmento de Lua que el menú lee al arrancar
|
|
y reescribe al cerrarse: `GAME_SELECTED` es el juego que estaba mostrando,
|
|
`SHOW_INTRO` es false cuando vuelve de un juego, para que no tengas que tragarte
|
|
la intro dos veces, y `MENU_OVERLAY` elige un renderizador (véase
|
|
<<menurenderers,Los dos renderizadores>>).
|
|
|
|
No todas las máquinas ejecutan todos los juegos. Un juego 3D en un aparato sin
|
|
3D, o un juego pesado en uno pequeño, fallaría o iría a paso de tortuga, así que
|
|
el menú te lo dice antes. Cuando seleccionas un juego que esta máquina no puede
|
|
ejecutar, la línea bajo sus detalles dice lo que necesita («Needs 3D, and this
|
|
machine has none.»), y al iniciarlo solo se repite eso en lugar de fallar a
|
|
medio camino. Un juego que pide más máquina que esta recibe «It may run
|
|
slowly.» y se inicia igualmente. No se oculta nada. El menú averigua lo rápida
|
|
que es esta máquina la primera vez que se reproduce su intro, cronometrando su
|
|
propio fondo, y guarda la respuesta en `machine.cfg`; nunca te pide que ejecutes
|
|
una prueba de rendimiento. Los juegos dicen lo que necesitan en su `games.dat`
|
|
(xref:Reference.adoc#gamesdat[REQUIRES y TIER]), y la herramienta Get Games
|
|
marca el catálogo del mismo modo.
|
|
|
|
[#menurenderers]
|
|
==== Los dos renderizadores
|
|
|
|
Un documento de la GUI se dibuja a través del dispositivo GPU que usa la escena
|
|
3D, así que en una máquina sin él no hay documento que construir. El menú se
|
|
encarga de eso por sí mismo: `Singe/Menu.singe` consulta
|
|
xref:Reference.adoc#singehasgpu[singeHasGpu] al arrancar y carga uno de los dos
|
|
renderizadores.
|
|
|
|
`Singe/MenuDocument.singe`::
|
|
El documento RmlUi descrito arriba, para una máquina con dispositivo GPU.
|
|
También dibuja la intro y la cuadrícula de detrás del menú como una sola escena
|
|
3D continua, así que el disco no se usa para ninguna de las dos.
|
|
|
|
`Singe/MenuOverlay.singe`::
|
|
Sprites y `fontPrint` directamente en el overlay, el aspecto que tenía Singe 2.
|
|
No necesita nada más allá del overlay en el que ya dibuja cada juego.
|
|
|
|
Los dos dibujan el mismo menú, aceptan las mismas teclas y ejecutan las mismas
|
|
herramientas de servicio; `Singe/Menu.singe` contiene todo lo que no es dibujar
|
|
-- la lista de juegos, la selección, iniciar un juego -- así que hay un solo menú
|
|
en lugar de dos. El renderizador del overlay muestra un juego cada vez en lugar
|
|
de una lista, ya que no tiene panel que desplazar, y recorta una descripción
|
|
demasiado larga para su columna en lugar de desplazarla.
|
|
|
|
Para ver el renderizador del overlay en una máquina que sí tiene GPU, pon
|
|
`MENU_OVERLAY = true` en `menu.dat` en la carpeta de datos del menú; el menú
|
|
vuelve a escribir la línea, así que se conserva. Así es como se prueba el camino
|
|
del overlay, y como lo consigue el montador de recreativas que prefiere el
|
|
aspecto antiguo.
|
|
|
|
[#onlineservice]
|
|
==== En línea: cuentas, juegos y puntuaciones
|
|
|
|
El menú incluido puede iniciar la sesión de la recreativa en un servicio maestro
|
|
(por defecto `master.singeengine.com`), que hace tres cosas: guarda la cuenta,
|
|
ofrece un catálogo de juegos para descargar y actualizar, y mantiene tablas de
|
|
récords.
|
|
|
|
Dos herramientas de servicio se encargan de ello. **Online Account** inicia
|
|
sesión, crea una cuenta, recupera una contraseña y establece la dirección del
|
|
servidor -- es donde un operador que gestiona su propio servicio apunta la
|
|
recreativa. Una cuenta nueva no se puede usar hasta que se abre el enlace
|
|
enviado por correo electrónico. **Get Games** muestra todo lo que ofrece el
|
|
servicio, marca lo que está instalado aquí y lo descarga, actualiza o quita. Una
|
|
descarga que contiene varios juegos -- una colección, o un juego en dos idiomas
|
|
-- pone cada uno de ellos en la lista con su propio nombre, indicando en qué
|
|
descarga viene, y descargar o quitar cualquiera de ellos descarga o quita todos,
|
|
ya que son un solo archivo. Lo que se ofrece depende de la cuenta: un servicio
|
|
puede reservar un juego para cuentas concretas, así que dos recreativas con la
|
|
sesión iniciada en cuentas distintas pueden ver listas distintas. El propio menú
|
|
avisa cuando existe una versión más reciente de un juego instalado: el juego
|
|
lleva una marca `update` en la lista, la línea bajo sus detalles indica la
|
|
versión, y el botón 3 en esa página la descarga, así que una recreativa no
|
|
necesita abrir una herramienta de servicio para estar al día. No se guarda en
|
|
ningún sitio nada sobre esta máquina: el menú lee la versión del propio
|
|
`games.dat` de cada juego y pregunta por su propia lista, así que un juego
|
|
copiado a mano se conoce igual que uno descargado aquí. Una recreativa sin
|
|
ningún juego abre igualmente el menú, que explica cómo conseguir algunos, y lo
|
|
que Get Games descargue o quite aparece en la lista en cuanto se cierran las
|
|
herramientas de servicio. Una lista más larga que la pantalla se desplaza con la
|
|
selección en lugar de salirse por abajo, con `...` para indicar que hay más en
|
|
un sentido u otro. Un juego que deja de ofrecerse sigue funcionando y se muestra
|
|
como «installed, no longer offered»: lo único que deja de pasar es que reciba
|
|
actualizaciones, porque un jugador que tiene un juego lo tiene. Una descarga se
|
|
comprueba con el hash que publicó el catálogo antes de que sustituya nada, así
|
|
que una transferencia que llega mal falla en lugar de instalar un juego que no
|
|
funcionará.
|
|
|
|
La cuenta pertenece a la *máquina*, no a un juego: el token se guarda en
|
|
`master.dat` en la raíz de datos, así que un juego que publica una puntuación usa
|
|
la misma sesión que inició el menú. La contraseña nunca se guarda, y el archivo
|
|
está ofuscado, así que el token y la dirección de la cuenta no se pueden sacar de
|
|
él de un vistazo; un archivo editado se lee como sin sesión. La máquina tiene que
|
|
poder volver a leerlo sin nadie delante, así que trata `master.dat` de todos
|
|
modos como una llave de la cuenta: copiado a otra máquina, inicia la sesión en
|
|
esa máquina. Publicar una puntuación necesita esa cuenta, pero leer una tabla de
|
|
récords no: una recreativa sin sesión sigue mostrando la tabla de récords en
|
|
línea de un juego, donde el juego muestre una, para cualquier juego que el
|
|
servicio ofrezca a todo el mundo. Véase
|
|
xref:Reference.adoc#onlinescores[Récords en línea] para la parte del juego, y
|
|
`Singe/Net.singe` para el cliente HTTP asíncrono que hay debajo -- nada de esto
|
|
bloquea un fotograma, porque Lua en Singe es cooperativo y una descarga grande
|
|
parecería si no un cuelgue.
|
|
|
|
Singe comprueba el certificado del servidor con dos listas a la vez: la que trae
|
|
consigo y la que guarda tu máquina. Basta con que una de las dos avale al
|
|
servidor, así que una copia antigua de Singe aún puede llegar a la actualización
|
|
que la sustituye siempre que tu sistema mantenga al día su propia lista.
|
|
¿Gestionas tu propio servicio con un certificado de tu propia autoridad? Pon el
|
|
certificado de esa autoridad en `cacerts.local.pem` en la carpeta de datos.
|
|
Singe nunca escribe ese archivo, así que sobrevive a las actualizaciones. Si se
|
|
rechaza una conexión, el mensaje dice qué listas se comprobaron, y un
|
|
certificado «not yet valid» casi siempre significa que el reloj de la máquina va
|
|
mal.
|
|
|
|
[#servicetools]
|
|
==== Las herramientas de servicio
|
|
|
|
La tecla asignada a `INPUT_SERVICE` abre una lista de herramientas sobre la
|
|
lista de juegos. Arriba y abajo eligen una y el botón 1 la abre; el botón 2 sale
|
|
de una herramienta a la lista, y la tecla de servicio otra vez sale de las
|
|
herramientas del todo. Todo está en `Singe/Tools.singe`, que el motor extrae
|
|
junto a `Menu.singe`. Ahí nada dibuja: una herramienta construye una lista de
|
|
filas y se la pasa al menú, y por eso todas las herramientas funcionan con los
|
|
dos renderizadores (véase <<menurenderers,Los dos renderizadores>>). Nada de
|
|
esto necesita que haya un juego en marcha, y nada cambia los archivos propios de
|
|
un juego.
|
|
|
|
Audio Delay::
|
|
El retardo del audio en la cadena de salida, medido con un clic y un destello.
|
|
Véase xref:Reference.adoc#menucalibration[Calibrar desde el menú] para saber qué
|
|
hace y por qué funciona.
|
|
|
|
Input Test::
|
|
Todos los mandos, ratones y pistolas que el motor ve, en directo: el último
|
|
interruptor que habría recibido el juego y cuántos han llegado, el nombre de
|
|
cada mando con sus seis ejes y los botones pulsados, y el nombre y la posición
|
|
de cada ratón. Esta es la pantalla que responde a «el botón no hace nada» -- o
|
|
el interruptor llega y el juego lo ignora, o no llega nunca.
|
|
|
|
System Information::
|
|
La versión del motor, el sistema operativo, el procesador y la memoria, el
|
|
renderizador y el dispositivo 3D, qué decodificadores de vídeo están en uso, los
|
|
formatos de audio incorporados, la SoundFont, el estado de MIDI, los tamaños de
|
|
la ventana, del lienzo y del overlay, y la carpeta de datos. Una foto de esta
|
|
página responde a la mayor parte de un informe de error.
|
|
|
|
Light Gun::
|
|
Dianas en el centro y en cada esquina del overlay, sobre lo que esté mostrando
|
|
el disco. El botón 1 marca dónde apuntó de verdad la pistola, y guarda los
|
|
últimos doce disparos; Start los borra. Una pistola bien alineada con la imagen
|
|
pone sus cruces sobre las dianas, y una que no lo está muestra hacia dónde se
|
|
desvía.
|
|
|
|
Sound Test::
|
|
El botón 1 reproduce el clic por el altavoz izquierdo, luego por el derecho y
|
|
luego por los dos, que es toda la comprobación de cables cruzados. También
|
|
muestra las pistas de audio propias del disco, e izquierda y derecha cambian
|
|
entre ellas.
|
|
|
|
Display::
|
|
El tamaño, la posición y la rotación de la imagen, cambiados en directo con las
|
|
flechas, los botones 3 y 4 y la moneda 1, sobre una carta de ajuste: una
|
|
cuadrícula de 16 por 12 para cuadrar la imagen, una cuña de grises de ocho
|
|
escalones para ajustar el brillo, y dos marcos separados un píxel en el mismo
|
|
borde -- un monitor con overscan se come primero el de fuera. El botón 1 guarda
|
|
los valores para esta máquina, en el mismo `machine.cfg` que usa el retardo de
|
|
audio, así que se aplican a todos los juegos en lugar de ajustarse una vez por
|
|
juego. Start lo deja todo como estaba.
|
|
|
|
Disc Test::
|
|
Doce saltos repartidos por todo el disco, cada uno cronometrado. Un rip cuyos
|
|
fotogramas clave están muy separados salta despacio, y el único síntoma en un
|
|
juego es que todo se nota pesado; esto lo mide directamente e informa del peor
|
|
de los doce. Un salto que no ha llegado en tres segundos cuenta como tres
|
|
segundos.
|
|
|
|
Saved Data::
|
|
Lo que ha guardado cada juego, encontrado buscando en la raíz de datos en lugar
|
|
de que se lo digan, con el tamaño de cada cosa. El botón 3 -- no el botón 1, que
|
|
es «elegir» en todas las demás partes -- tira la partida guardada del juego
|
|
seleccionado. Borrar una tabla de récords sin borrar el juego es el motivo
|
|
habitual.
|
|
|
|
Engine Update::
|
|
Un Singe más reciente, cuando el servicio tiene uno para esta máquina. Una beta
|
|
lleva la versión `3.00b2`, la segunda beta de la 3.00, y va antes que la propia
|
|
3.00, así que a una recreativa con una beta se le ofrece la versión final el
|
|
mismo día que se publica. Muestra lo que está en marcha y lo que se ofrece, y el
|
|
botón 1 lo descarga, lo comprueba con el hash que publicó el servicio, lo pone
|
|
junto al Singe en marcha con el nombre propio de la versión, aparta el antiguo
|
|
como `old-<name>` y se reinicia con el nuevo. Apartar el antiguo puede no ser
|
|
posible, por una carpeta en la que este usuario no puede escribir o por un
|
|
antivirus que tiene el archivo abierto; la herramienta lo dice y sigue adelante,
|
|
ya que el lanzador ejecuta de todos modos el Singe más reciente de la carpeta.
|
|
El nuevo Singe arranca con `--refresh`, así que la carpeta de soporte la
|
|
reescribe la versión que ahora es su dueña y la antigua se conserva como
|
|
`old-Singe-<version>`; un archivo que traía un Singe anterior y que este no trae
|
|
no puede quedarse por ahí y confundir a un juego. No pasa nada hasta pulsar ese
|
|
botón. El botón 3 vuelve a preguntar al servicio. El menú mira una vez al día
|
|
por su cuenta y lo indica en una línea bajo los detalles del juego;
|
|
`no_update_check = true` en `settings.cfg` detiene la consulta diaria, y la
|
|
herramienta sigue funcionando a mano.
|
|
|
|
Online Account::
|
|
Iniciar la sesión de esta recreativa en el servicio maestro, crear una cuenta,
|
|
recuperar una contraseña y establecer la dirección del servidor. Véase
|
|
<<onlineservice,En línea: cuentas, juegos y puntuaciones>>.
|
|
|
|
Get Games::
|
|
El catálogo: lo que ofrece el servicio, lo que está instalado aquí, y
|
|
descargarlo, actualizarlo o quitarlo.
|
|
|
|
MIDI Ports::
|
|
Los puertos de entrada y salida que tiene esta máquina, cuáles de ellos ha
|
|
abierto Singe y los últimos mensajes que han llegado. El botón 1 envía una nota,
|
|
el botón 3 vuelve a buscar puertos después de conectar algo. No se abre nada
|
|
hasta que esta herramienta lo pide, así que una recreativa que nunca toca MIDI
|
|
nunca paga por ello.
|
|
|
|
Frame Statistics::
|
|
Activa y desactiva el overlay del desarrollador. Sigue activo dentro del juego,
|
|
en la esquina superior izquierda. Véase xref:Reference.adoc#statsenable[statsEnable].
|
|
|
|
[[controls]]
|
|
== Controles
|
|
|
|
Por defecto, Singe asigna los mandos como si fueran mandos de Xbox. Si tu mando
|
|
no se reconoce o quieres cambiar las asignaciones por defecto tal y como las ve
|
|
Singe, puedes usar la herramienta gratuita SDL2 Gamepad Tool de
|
|
http://generalarcade.com/gamepadtool/.
|
|
|
|
[[controlscfg]]
|
|
=== controls.cfg
|
|
|
|
Además de configurar tu mando, puedes reasignar todas las opciones de entrada de
|
|
Singe en su conjunto o de cualquier juego concreto con archivos `controls.cfg`.
|
|
Para decidir cómo se asignan las entradas, Singe lee los ajustes de configuración
|
|
en el orden siguiente, y un archivo posterior sustituye a uno anterior entrada por
|
|
entrada (véase <<configorder,Dónde se leen los archivos de configuración>>):
|
|
|
|
. Los valores por defecto incluidos en Singe.
|
|
. `controls.cfg` de la carpeta del script principal del juego: lo que distribuyó el autor del juego.
|
|
. `controls.cfg` de la carpeta desde la que se inició Singe: el de la propia máquina (la carpeta `Singe` contiene una plantilla `controls.cfg.example` que puedes copiar).
|
|
. `controls.cfg` de la carpeta que está por encima de la carpeta de datos del juego.
|
|
. `controls.cfg` de la carpeta de datos del juego: el tuyo, para ese juego concreto.
|
|
|
|
No tienes que especificar todas las opciones en un archivo `controls.cfg`
|
|
personalizado. Basta con que pongas las entradas que quieras cambiar.
|
|
|
|
Después de instalar Singe, encontrarás un archivo de ejemplo de configuración de
|
|
entradas en `<InstallDir>/Singe/controls.cfg.example`. Para ver las opciones de
|
|
configuración que puedes usar en este archivo, repasa
|
|
`<InstallDir>/Singe/Framework.singe`.
|
|
|
|
`--keymapfile` indica un único archivo que leer en lugar de hacer esa búsqueda, lo
|
|
que resulta útil a un front-end que no quiere ninguna duda sobre qué asignaciones
|
|
recibió un juego.
|
|
|
|
Cada entrada `INPUT_` es una lista, y cualquier elemento de ella acciona el
|
|
interruptor. Una lista dentro de esa lista es una combinación: de dos a cuatro
|
|
teclas o botones pulsados a la vez, que acciona el interruptor cuando se pulsa el
|
|
último de ellos y lo suelta cuando se levanta cualquiera. Así es como una consola
|
|
portátil sin tecla Escape sale con Select y Start a la vez:
|
|
|
|
[source,lua]
|
|
----
|
|
INPUT_QUIT = { SCANCODE.ESCAPE, { GAMEPAD_0.BUTTON_BACK, GAMEPAD_0.BUTTON_START } }
|
|
----
|
|
|
|
Cada tecla o botón de una combinación conserva además su propio significado, así
|
|
que pulsar Select y Start para salir de esta forma también echa una moneda y pulsa
|
|
Start de camino a la salida.
|
|
|
|
Si quieres una forma de salir que funcione siempre, usa `--quitchord` en su lugar.
|
|
Cuando pulsas uno de sus botones, Singe espera un cuarto de segundo al resto antes
|
|
de hacer nada más, así que salir no echa una moneda ni pulsa Start. Un juego puede
|
|
desactivar su propia tecla de salida, pero no puede desactivar `--quitchord`.
|
|
|
|
[[devices]]
|
|
=== Todo dispositivo es un mando
|
|
|
|
Singe tiene una sola familia de mandos, de `GAMEPAD_0` a `GAMEPAD_3`, y todo
|
|
dispositivo que abre pertenece a ella. SDL solo llama mando a un dispositivo
|
|
cuando tiene una asignación para él, y una placa encoder de recreativa, un
|
|
spinner, un volante o un joystick de vuelo a menudo no la tiene. En lugar de
|
|
arrastrar un segundo tipo de dispositivo con sus propios nombres, Singe escribe él
|
|
mismo una asignación para ese dispositivo y luego lo abre como un mando corriente,
|
|
de modo que llega a `controls.cfg`, `controllerGetAxis`,
|
|
`controllerGetButton` y a todos los interruptores `INPUT_*` exactamente igual que
|
|
un mando reconocido.
|
|
|
|
La asignación que escribe Singe es directa: los ejes del dispositivo, en orden,
|
|
pasan a ser el stick izquierdo, el stick derecho y luego los dos gatillos; sus
|
|
botones, en orden, pasan a ser `BUTTON_A`, `BUTTON_B`, `BUTTON_X`, `BUTTON_Y`,
|
|
`BUTTON_BACK`, `BUTTON_GUIDE`, `BUTTON_START`, `BUTTON_LEFT_STICK`,
|
|
`BUTTON_RIGHT_STICK`, `BUTTON_LEFT_BUMPER` y `BUTTON_RIGHT_BUMPER`; y su primer
|
|
hat pasa a ser la cruceta. Un dispositivo sin hat dedica en su lugar sus cuatro
|
|
botones siguientes a la cruceta. **Un dispositivo con más controles de los que el
|
|
modelo de mando puede nombrar pierde los que sobran** -- más de seis ejes, más de
|
|
quince botones o un segundo hat -- y un dispositivo cuyos botones no estén
|
|
cableados en ese orden los tendrá en los sitios equivocados. Ese es el precio de
|
|
una familia en lugar de dos, y es fácil de corregir: `--program` escribe en la
|
|
traza la asignación que creó, en el formato propio de SDL, así que puedes pegarla
|
|
en un `gamecontrollerdb.txt`, reordenarla y hacer que se use esa.
|
|
|
|
`--mapjoysticks=false` desactiva esa escritura, y en ese caso un dispositivo que
|
|
SDL no reconoce no se abre en absoluto, exactamente como en versiones anteriores.
|
|
|
|
[[gamecontrollerdb]]
|
|
=== gamecontrollerdb.txt
|
|
|
|
SDL incluye una gran base de datos de asignaciones de mandos, y la comunidad
|
|
mantiene una más grande -- `gamecontrollerdb.txt`, de
|
|
https://github.com/mdqinc/SDL_GameControllerDB. Singe busca ese archivo en los
|
|
mismos cuatro sitios en los que busca `controls.cfg`, en el mismo orden (véase
|
|
<<configorder,Dónde se leen los archivos de configuración>>):
|
|
|
|
. la carpeta del script principal del juego;
|
|
. la carpeta desde la que se inició Singe;
|
|
. la carpeta que está por encima de la carpeta de datos del juego;
|
|
. la carpeta de datos del juego.
|
|
|
|
Se cargan todos los archivos encontrados, en ese orden, así que el archivo de la
|
|
máquina gana al que distribuye un juego, un archivo en la carpeta de datos del
|
|
juego gana a los dos y todos ellos ganan a la propia base de datos de SDL. Solo un dispositivo que ninguno de ellos
|
|
nombra recibe la asignación que Singe escribe para él: esa es el último recurso,
|
|
nunca una rival de tus archivos. `--program` informa de cuántas asignaciones
|
|
añadió cada archivo.
|
|
|
|
Los archivos también ganan a `SDL_GAMECONTROLLERCONFIG`, la variable de entorno de
|
|
la que SDL toma asignaciones, que algunas consolas portátiles definen para su mando
|
|
integrado. La asignación de ArkOS para la R36S, por ejemplo, deja fuera Select y
|
|
Start, así que ningún juego los ve; una línea en `gamecontrollerdb.txt` para el
|
|
mismo mando los devuelve. SDL lee la variable una sola vez, cuando arranca Singe,
|
|
así que esto vale para los archivos que encuentra el primer juego. Un juego
|
|
iniciado después desde el menú sigue leyendo los suyos, pero un mando que la
|
|
variable nombra conserva la asignación de la variable.
|
|
|
|
Una línea de ese archivo tiene este aspecto, y es exactamente lo que imprime la
|
|
traza para un dispositivo que Singe asignó por sí mismo:
|
|
|
|
----
|
|
ff00d87a475300004900000000007603,Arcade Encoder,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b4,guide:b5,start:b6,leftx:a0,lefty:a1,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
----
|
|
|
|
|
|
[[deadzones]]
|
|
=== Zonas muertas y gatillos
|
|
|
|
`DEAD_ZONE` en `controls.cfg` es cuánto debe moverse un eje antes de contar como
|
|
un interruptor pulsado, en las unidades en bruto que da SDL: `32767` con el eje a
|
|
fondo, así que el valor por defecto de `15000` es algo menos de la mitad del
|
|
recorrido. Abarca todos los ejes de todos los mandos, incluidos los dos gatillos
|
|
analógicos, y un script lo lee como `SINGE_DEAD_ZONE`.
|
|
|
|
Dos ajustes lo afinan más.
|
|
|
|
`DEAD_ZONES` es una lista de pares `{ axis, dead zone }`, para un eje cada vez, en
|
|
esas mismas unidades en bruto, para un stick duro o un gatillo gastado sin tocar
|
|
todo lo demás:
|
|
|
|
[source,lua]
|
|
----
|
|
DEAD_ZONES = {
|
|
{ GAMEPAD_0.AXIS_LEFT_X, 8000 },
|
|
{ GAMEPAD_1.AXIS_LEFT_TRIGGER, 30000 },
|
|
}
|
|
----
|
|
|
|
El eje puede escribirse como el propio eje o como cualquiera de sus dos direcciones
|
|
(`GAMEPAD_0.AXIS_LEFT_X`, `AXIS_LEFT_X_L` y `AXIS_LEFT_X_R` nombran todos el mismo
|
|
eje). Todo lo que no esté en la lista conserva `DEAD_ZONE`.
|
|
|
|
`TRIGGER_THRESHOLD` es cuánto debe recorrer un gatillo analógico antes de contar
|
|
como un botón, expresado como *porcentaje del recorrido completo*, que es la
|
|
unidad que usa `-trigger-threshold` de Hypseus y cuyo valor por defecto allí es
|
|
`99.5`. Se aplica a los dos gatillos de los cuatro mandos. El valor por defecto de
|
|
Singe es `0`, lo que significa que los gatillos siguen con `DEAD_ZONE`, así que
|
|
nada cambia para quien no lo pida; un script lee el resultado en unidades en bruto
|
|
como `SINGE_TRIGGER_THRESHOLD`. Las dos unidades se convierten directamente: un uno
|
|
por ciento son `32767 / 100` unidades en bruto, así que el `DEAD_ZONE` de `15000`
|
|
de Singe es un `45.8` por ciento y el `99.5` por ciento de Hypseus son `32603`
|
|
unidades en bruto. `--trigger_threshold` fija el mismo número desde la línea de
|
|
comandos y gana a `controls.cfg`; `DEAD_ZONES` gana a los dos, por ser el más
|
|
específico.
|
|
|
|
[[joymouse]]
|
|
=== Mover el ratón con un stick
|
|
|
|
Un juego de pistola de luz en una recreativa con stick y sin ratón no se puede
|
|
jugar a menos que el stick pueda mover el cursor. `--joymouse` hace que lo mueva:
|
|
el **stick izquierdo del mando de la ranura 0** mueve el puntero que ve el juego, a
|
|
través del mismo `onMouseMoved` al que llega un ratón real, y el cursor se mantiene
|
|
dentro de la imagen. `--js_range` es la velocidad, de `1` a `20` con `5` por
|
|
defecto, medida en píxeles de vídeo por fotograma con el stick a fondo, así que
|
|
`5` cruza una imagen de 720 píxeles en unos dos segundos. El eje respeta su propia
|
|
zona muerta, así que un stick con deriva no hace que el cursor se vaya desplazando
|
|
solo.
|
|
|
|
Está desactivado por defecto, y en eso Singe se diferencia de Hypseus: el
|
|
`controls.cfg` que se incluye ya asigna ese stick a `INPUT_UP`, `INPUT_DOWN`,
|
|
`INPUT_LEFT` y `INPUT_RIGHT`, y que además moviera el cursor sin que nadie lo
|
|
pidiera sorprendería a todos los juegos existentes. `--joymouse=false` equivale a
|
|
`-nojoymouse` de Hypseus, y un script lo activa y desactiva con `joyMouseEnable`
|
|
y lo consulta con `joyMouseIsEnabled`. Una recarga lo deja como lo dejó la línea
|
|
de comandos.
|
|
|
|
[[mousedevices]]
|
|
=== Ratones, pistolas y quién decide
|
|
|
|
`mouseSetMode(MOUSE_MANY)` es la decisión de un juego de distinguir hasta cuatro
|
|
ratones, algo que una recreativa de dos pistolas necesita y que no se le puede dar
|
|
a un juego que nunca hace esa llamada. `--manymouse` es la decisión del usuario y
|
|
tiene prioridad sobre ella: el modo está activo desde el principio y
|
|
`mouseSetMode(MOUSE_SINGLE)` ya no lo desactiva.
|
|
|
|
`--absolutes_only` se queda solo con los dispositivos que informan de una posición
|
|
absoluta, que es lo que hace una pistola de luz de verdad y no hace un ratón
|
|
corriente, así que una recreativa con dos pistolas y un ratón de escritorio
|
|
enchufado no se confunde por culpa del ratón. Ten en cuenta cómo lo decide:
|
|
**ManyMouse, el backend que usa Singe para distinguir los ratones, no ofrece
|
|
ninguna forma de preguntar a un dispositivo de qué tipo es**, así que un
|
|
dispositivo cuenta como absoluto en cuanto ha informado de una posición absoluta,
|
|
y no antes. Una pistola lo hace con su primer movimiento; hasta entonces está en
|
|
silencio, y un dispositivo solo relativo se queda en silencio para siempre. Por
|
|
tanto, la opción es un filtro por comportamiento observado y no por clase de
|
|
dispositivo, y en una máquina donde ningún dispositivo informa nunca de una
|
|
posición absoluta silencia todos los ratones.
|
|
|
|
`SWITCH_MOUSE_DISCONNECT` es un interruptor como cualquier otro, salvo que no lo
|
|
produce ninguna tecla ni botón: el motor lo lanza cuando se desenchufa un ratón o
|
|
una pistola de luz, una vez como pulsación y otra como liberación, para que un
|
|
juego de pistolas pueda indicarlo en pantalla en lugar de parecer que se ha
|
|
colgado. Es el interruptor de Hypseus del mismo nombre. `controls.cfg` no lo
|
|
asigna a nada; asígnale también una tecla si quieres ver qué hace un juego sin
|
|
tener que tirar de un cable.
|
|
|
|
[[hotkeys]]
|
|
=== Teclas rápidas
|
|
|
|
`Alt-Enter` alterna entre pantalla completa y ventana mientras el juego está en
|
|
marcha, igual que en Hypseus. El juego nunca ve la tecla. Una ventana que empezó
|
|
en pantalla completa exclusiva (`--fullscreen`) vuelve a ella en el modo de
|
|
pantalla que se le dio; una que empezó en ventana pasa a una ventana sin bordes
|
|
que cubre el escritorio. No hace falta cambiar nada más: el renderizador presenta
|
|
un tamaño lógico en coordenadas de vídeo y lo escala a lo que mida ahora la
|
|
ventana, el rectángulo del vídeo se construye en esas mismas coordenadas y el
|
|
destino de la rotación tiene el tamaño de la imagen y no el de la ventana, así que
|
|
la imagen, el overlay, las GUI y la correspondencia del ratón se ajustan solos.
|
|
|
|
Los demás interruptores que puede pulsar un usuario -- salir, pausa, captura de
|
|
pantalla, grabación, la consola y el conmutador de captura del ratón -- son
|
|
asignaciones normales de `controls.cfg` y se describen junto a los nombres
|
|
`INPUT_*` en el archivo de ejemplo.
|
|
|
|
[[recording]]
|
|
=== Grabar vídeo
|
|
|
|
`F10` empieza a grabar el juego, imagen y sonido a la vez, y `F10` de nuevo
|
|
detiene la grabación. Cada grabación es un nuevo `singeNNN.mp4` en la carpeta de
|
|
datos del juego, junto a las capturas de pantalla, y se reproduce en cualquier
|
|
cosa que reproduzca un MP4. La imagen es la ventana entera tal como la ves, bandas
|
|
negras incluidas, y el sonido es todo lo que suena en el juego: la música, los
|
|
efectos de sonido y la propia banda sonora del vídeo.
|
|
|
|
Si la máquina tiene un codificador de vídeo por hardware, Singe lo usa, así que
|
|
grabar le cuesta muy poco al juego: H.264 mediante VA-API en Linux, VideoToolbox
|
|
en macOS, Media Foundation en Windows y V4L2 en las placas ARM que tienen uno. En
|
|
cualquier otro caso graba MPEG-4, que se reproduce en todas partes pero genera
|
|
archivos más grandes. La línea `Recording` de la traza dice cuál usó. Una máquina
|
|
demasiado lenta para seguir el ritmo descarta fotogramas de la grabación en lugar
|
|
de ralentizar el juego, y la traza dice cuántos cuando se detiene la grabación.
|
|
|
|
Para grabar en cambio una sesión entera, inicia Singe con `--record=FILENAME`.
|
|
Añade `--deterministic` y Singe grabará cada fotograma y el sonido exacto que lo
|
|
acompaña, tarde lo que tarde en generarse cada fotograma, sin reproducir nada por
|
|
los altavoces. Así es como se hace un vídeo perfecto de una demo o de un modo de
|
|
atracción: en un ordenador de sobremesa suele ir más rápido que en tiempo real.
|
|
[#_settings_and_options]
|
|
== Ajustes y opciones
|
|
|
|
Casi todo lo que puedes poner en la línea de comandos puede ir también en un
|
|
archivo de ajustes. Configúralo una vez y todos los juegos lo usan.
|
|
|
|
[[settings]]
|
|
=== El archivo de ajustes
|
|
|
|
Casi todo lo de la línea de comandos se puede escribir también una sola vez, en
|
|
un archivo `settings.cfg`, para que una recreativa no necesite un script lanzador
|
|
que lleve la misma docena de opciones para cada juego. Es Lua, como
|
|
`controls.cfg`, y Singe lo busca exactamente en los mismos cuatro sitios, en
|
|
este orden:
|
|
|
|
. `settings.cfg` de la carpeta del script principal del juego.
|
|
. `settings.cfg` de la carpeta desde la que se inició Singe (la carpeta `Singe` contiene una plantilla `settings.cfg.example` que puedes copiar).
|
|
. `settings.cfg` de la carpeta que está por encima de la carpeta de datos del juego.
|
|
. `settings.cfg` de la carpeta de datos del juego.
|
|
|
|
Cada sitio se lee una vez, y un archivo posterior gana clave por clave, así que
|
|
un archivo para toda la máquina puede fijar la pantalla y los volúmenes mientras
|
|
un archivo en la carpeta de datos de un juego desactiva el punto de mira de ese
|
|
juego. No tienes que escribir todas las claves en un archivo; escribe las que
|
|
quieras cambiar.
|
|
|
|
Cada clave es el nombre largo de una opción de línea de comandos sin los guiones
|
|
iniciales, así que no hay un segundo vocabulario que aprender:
|
|
|
|
[source,lua]
|
|
----
|
|
-- El settings.cfg de la propia recreativa
|
|
screen = 2 -- el segundo monitor
|
|
fullscreen = true
|
|
volume_vldp = 80
|
|
haptic = 0 -- esta recreativa no tiene vibración
|
|
idleexit = 900 -- devuelve la pantalla tras quince minutos sin actividad
|
|
startsilent = true
|
|
----
|
|
|
|
Una opción que no lleva valor en la línea de comandos lleva aquí `true` o
|
|
`false` (también se aceptan `yes`, `no`, `on`, `off`, `1` y `0`). Ponerla a
|
|
`false` es lo mismo que no ponerla. Una opción que lleva un valor lleva aquí el
|
|
mismo valor que en la línea de comandos, como número o como cadena.
|
|
|
|
Una opción, `--deterministic`, lleva un valor o no lo lleva, y su clave hace lo
|
|
mismo: `deterministic = true` usa el paso por defecto, `deterministic = 20`
|
|
indica uno, y `deterministic = false` deja la opción desactivada.
|
|
|
|
[[configorder]]
|
|
=== Dónde se leen los archivos de configuración
|
|
|
|
`controls.cfg`, `settings.cfg` y `gamecontrollerdb.txt` se buscan todos en los
|
|
mismos cuatro sitios, en el mismo orden, y un archivo leído después gana a uno
|
|
leído antes:
|
|
|
|
. *La carpeta del script principal del juego,* que para un juego empaquetado
|
|
está dentro de su archivo `.game`. Es lo que distribuyó el autor del juego,
|
|
así que se lee primero: fija los valores por defecto del juego y nada más.
|
|
. *La carpeta desde la que se inició Singe.* Aquí van los archivos propios de la
|
|
máquina, como la disposición de botones de una consola portátil, y ganan a lo
|
|
que distribuye un juego. Un archivo solo sustituye lo que nombra, así que para
|
|
quitar de un botón una asignación de un juego, nombra esa entrada:
|
|
`INPUT_TEST_MODE = { SCANCODE.F2 }` en el `controls.cfg` de la máquina deja el
|
|
modo de prueba solo en el teclado, sea cual sea el botón en el que lo pusiera
|
|
un juego.
|
|
. *La carpeta que está por encima de la carpeta de datos del juego,* para los
|
|
archivos que comparten todos los juegos que usan esa carpeta de datos.
|
|
. *La carpeta de datos del juego.* Tus propios archivos para un juego, que ganan
|
|
a todo lo demás.
|
|
|
|
Con `--datadir=.`, la carpeta de datos es la propia carpeta del juego, en cuyo
|
|
caso el archivo que hay ahí se lee una sola vez, como el del juego.
|
|
`--keymapfile` sustituye toda la búsqueda de `controls.cfg` por un único archivo
|
|
indicado.
|
|
|
|
[#_what_wins]
|
|
=== Qué prevalece
|
|
|
|
. El valor por defecto incorporado.
|
|
. El archivo de ajustes.
|
|
. La entrada del juego en `games.dat`, para el puñado de ajustes que lleva (véase xref:Reference.adoc#gamesdat[games.dat]).
|
|
. `machine.cfg`, para el retardo de audio y la geometría de la imagen que guardan
|
|
las herramientas de servicio (véase <<servicetools,Las herramientas de servicio>>).
|
|
. La línea de comandos, que siempre gana.
|
|
|
|
Un archivo de ajustes es, dicho de otro modo, un conjunto de valores por defecto,
|
|
no algo que hayas tecleado: si una entrada de `games.dat` da a un juego una
|
|
resolución o un borde Sinden, esa entrada sigue describiendo el juego mejor que
|
|
un archivo para toda la máquina. Lo que se teclea de verdad en la línea de
|
|
comandos gana a los dos. `machine.cfg` queda justo por debajo de la línea de
|
|
comandos porque alguien ajustó la imagen mirando este monitor, lo cual es mejor
|
|
prueba que cualquier archivo escrito en otra parte; el retardo de audio es una
|
|
excepción total a este orden, ya que se suma al retardo del juego en lugar de
|
|
sustituirlo.
|
|
|
|
Las opciones que nombran el juego (`--framefile`, `--disc`, `--entry`), nombran
|
|
una carpeta (`--gamedir`, `--datadir`), tienen que actuar antes de que se pueda
|
|
encontrar el archivo (`--help`, `--apiversion`, `--noconsole`, `--pack`,
|
|
`--patch`, `--unpack`) o son para una sola ejecución (`--record`, `--refresh`)
|
|
no se pueden fijar en un archivo de ajustes. Una clave que no es una opción, o que es una de esas, o un valor que la opción no acepta, es
|
|
un error que nombra el archivo y la clave, así que una errata nunca se ignora en
|
|
silencio:
|
|
|
|
----
|
|
settings.cfg: volume_vldpp is not an option.
|
|
settings.cfg: datadir cannot be set here; it belongs on the command line.
|
|
settings.cfg: Display scale must be between 25 and 100 percent.
|
|
----
|
|
|
|
Con `--program` o `--trace`, la cabecera al principio de `trace.txt` enumera
|
|
todos los ajustes que se aplicaron, así que nunca hay dudas sobre qué archivo
|
|
recibió un juego en marcha.
|
|
|
|
[[commandlineoptions]]
|
|
=== Opciones de línea de comandos
|
|
|
|
----
|
|
Singe [OPTIONS] gameName
|
|
----
|
|
|
|
El nombre del juego es el único argumento obligatorio. Puede ser un script
|
|
`.singe`, una carpeta que contiene un script con el mismo nombre (`MyGame`
|
|
encuentra `MyGame/MyGame.singe`) o un juego empaquetado (`MyGame.game` ejecuta
|
|
la primera entrada del `games.dat` que lleva dentro, `--entry=N` otra). Un
|
|
script o una carpeta iniciados así se ejecutan también con su entrada de
|
|
`games.dat` cuando hay una que los nombra (véase
|
|
xref:Reference.adoc#gamesdat[games.dat]), así que un juego funciona igual desde
|
|
la línea de comandos que desde el menú. Para un juego de laserdisc (`--disc`)
|
|
sin `--framefile`, Singe busca junto al script un vídeo con el mismo nombre base
|
|
y cualquier extensión que FFmpeg sepa desmultiplexar, y luego un framefile
|
|
`.txt`.
|
|
|
|
Las opciones están agrupadas según lo que hacen.
|
|
|
|
[#_the_game_and_its_files]
|
|
==== El juego y sus archivos
|
|
|
|
Qué juego se ejecuta, dónde están él y sus datos, y en qué se juega.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `-C`, `--canvas=WxH` | Tamaño del mundo para un juego sin disco, 720x480 por defecto. Se ignora cuando hay disco.
|
|
| `-d`, `--datadir=PATHNAME` | Carpeta para todo lo que escribe Singe: índices de vídeo, `trace.txt`, capturas de pantalla, partidas guardadas, el `menu.dat` del menú. Dentro se crea una subcarpeta con el nombre de la carpeta del juego (para un juego empaquetado, una con el nombre de la base de datos y, dentro de ella, otra con el de la carpeta del script). Por defecto, `data` en la carpeta de juegos. Singe 2.x escribía en cambio junto al juego; las carpetas de juegos pueden ser de solo lectura, así que ya no se escribe nada ahí.
|
|
| `-D`, `--disc` | Reproduce un vídeo de laserdisc: el indicado con `--framefile`, o el vídeo que se encuentre junto al script. `--framefile` la implica. Sin ella, un vídeo junto al script se notifica y se ignora.
|
|
| `-E`, `--entry=N` | Ejecuta la N-ésima entrada del `games.dat` que hay dentro de un archivo `.game` (1 por defecto). Véase xref:Reference.adoc#singlefile[Juegos de un solo archivo].
|
|
| `-v`, `--framefile=FILENAME` | Archivo de vídeo o framefile que usar en lugar del que se encuentre junto al script.
|
|
| `-G`, `--gamedir=PATHNAME` | La carpeta que contiene los juegos, los archivos `.game` empaquetados y la carpeta de soporte `Singe`, cuando el ejecutable está en otro sitio. Pasa a ser la carpeta de trabajo, así que el nombre del juego, un `--datadir` relativo y los nombres del empaquetador cuentan todos a partir de ella; las rutas absolutas funcionan tal cual. Por defecto, la carpeta actual.
|
|
| `-c`, `--showcalculated` | Muestra los rangos de fotogramas de cada segmento de un framefile, para depurar.
|
|
|===
|
|
|
|
[#_display]
|
|
==== Pantalla
|
|
|
|
La ventana y cómo la llena la imagen.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `-a`, `--aspect=N:D` | Fuerza la relación de aspecto que se usa para elegir el tamaño de la ventana (`4:3`, `16:9`, `16:10`).
|
|
| `-f`, `--fullscreen` | Pantalla completa exclusiva a la resolución del escritorio.
|
|
| `-w`, `--fullscreen_window` | Ventana sin bordes que cubre el escritorio.
|
|
| `--linearscale=BOOLEAN` | Suaviza el overlay cuando la ventana lo escala (`true`) o toma el píxel más cercano (`false`, que mantiene nítido el pixel art). Acepta `true`, `false`, `yes`, `no`, `on`, `off`, `1` o `0`. Un script lo cambia en marcha con `setOverlayLinearScale`. Por defecto: `true`, que es como han dibujado todas las versiones de Singe; el valor por defecto del propio Hypseus es el contrario.
|
|
| `-k`, `--nologos` | Omite las pantallas de presentación.
|
|
| `-r`, `--rotate=DEGREES` | Gira toda la presentación `0`, `90`, `180` o `270` grados en el sentido de las agujas del reloj, para una recreativa cuyo monitor está montado de lado. El vídeo, el overlay, las GUI, la escena 3D y las partículas giran juntos, un cuarto de vuelta intercambia la forma de la imagen para que se llene una ventana vertical, y las posiciones del ratón y de la pistola de luz se giran de vuelta para que un clic siga cayendo donde se dibuja. Solo se aceptan los cuatro ángulos rectos. Un script puede cambiarlo con `vldpSetRotate`.
|
|
| `--screen=N` | Abre la ventana en la pantalla `N`, contando desde `1` como las cuenta Hypseus. Un número mayor que el número de pantallas muestra las pantallas que hay y sale. Por defecto: la pantalla principal.
|
|
| `-u`, `--stretch` | Estira el vídeo para llenar la ventana en lugar de mantener su relación de aspecto.
|
|
| `-x`, `--xresolution=VALUE` | Anchura de la ventana. Si se omite la altura, se toma de la entrada correspondiente de la tabla de resoluciones incorporada. Un tamaño mayor que la pantalla -- pedido aquí o por el `games.dat` de un juego -- se reduce para que quepa, manteniendo su forma, y la traza lo indica. Al ejecutarse sin pantalla, con `SDL_VIDEODRIVER=offscreen`, no hay pantalla a la que ajustarse, y la ventana conserva el tamaño pedido.
|
|
| `-y`, `--yresolution=VALUE` | Altura de la ventana.
|
|
|===
|
|
|
|
[#_picture_placement_bezels_and_guns]
|
|
==== Colocación de la imagen, bezels y pistolas
|
|
|
|
Para una recreativa: dónde se coloca la imagen, el arte que la rodea y el borde que sigue una pistola Sinden. Véase <<cabinet,Montar una recreativa>>.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `-B`, `--bezel=FILENAME` | Dibuja arte de recreativa alrededor de la imagen. El archivo se busca en la carpeta `bezels` de la carpeta de juegos (un juego empaquetado puede llevar el suyo) y luego en la carpeta `bezels` de la carpeta de datos; `--bezeldir` indica otra carpeta. Sirve cualquier formato que lea SDL_image, y se conserva la transparencia. Un archivo complementario a su lado dice dónde va la imagen dentro de él; si no lo hay, la imagen conserva toda la ventana y la colocan `--shiftx`, `--shifty` y `--scalefactor`. Si el arte no se encuentra, el programa termina. Véase <<bezels,Bezels>>.
|
|
| `-I`, `--bezeldir=PATHNAME` | La carpeta que contiene el arte de `--bezel`, en lugar de `bezels`. Relativa a la carpeta de juegos, o absoluta. Solo se busca en esa carpeta. Véase <<bezels,Bezels>>.
|
|
| `-F`, `--bezelflip` | Dibuja el arte del bezel delante de la imagen en lugar de detrás, que es lo que hace Hypseus con sus propios bezels; la transparencia del arte es entonces el hueco por el que se ve el juego. Sin ella, el arte queda detrás de todo y la imagen tapa su recorte. Un script elige si el overlay y las GUI quedan por encima del arte con `setOverlayOnTop`. Véase <<bezels,Bezels>>.
|
|
| `-b`, `--scalefactor=PERCENT` | Reduce la imagen alrededor de su centro al `PERCENT` (de `25` a `100`) de la ventana, para pantallas que pierden los bordes por el overscan. Las posiciones del ratón y de la pistola de luz siguen a la imagen reducida. Un script puede cambiarlo mientras el juego se ejecuta con `vldpSetScale`. Se combina con `--shiftx`, `--shifty`, `--rotate` y `--sindengun`; véase <<videorect,El rectángulo de vídeo>>.
|
|
| `-X`, `--shiftx=PERCENT` | Mueve la imagen en horizontal dentro del espacio que le dejó `--scalefactor`, de `-100` (pegada a la izquierda) a `100` (pegada a la derecha), `0` centrada. Como en Hypseus, el desplazamiento es un porcentaje de ese espacio y nada más, así que con `--scalefactor=100` no hay espacio y el desplazamiento no hace nada: reduce antes la escala. Véase <<videorect,El rectángulo de vídeo>>.
|
|
| `-Y`, `--shifty=PERCENT` | Mueve la imagen en vertical dentro del espacio que le dejó `--scalefactor`, de `-100` (pegada arriba) a `100` (pegada abajo), `0` centrada. No hace nada a escala completa, por el mismo motivo. Véase <<videorect,El rectángulo de vídeo>>.
|
|
| `-S`, `--sindenedge=WHERE` | Dónde se coloca el borde Sinden: `video` lo dibuja alrededor de la imagen, `window` en el borde de la pantalla. Sin la opción, decide el bezel: con arte alrededor de la imagen el borde va al borde de la ventana, porque la cámara de la pistola ve toda la pantalla, y sin arte va alrededor de la imagen, como siempre. En el borde de la ventana, los dos anillos se dibujan como anillos, lo último de todo, así que el arte que queda entre ellos y la imagen sigue visible. Véase <<bezels,Bezels>>.
|
|
| `-g`, `--sindengun='PARAMS'` | Dibuja el borde que sigue una pistola de luz Sinden y traslada las posiciones del ratón y de la pistola de luz a la imagen que queda dentro: el anillo negro, si se indica, recorre el borde del vídeo, el anillo blanco va dentro de él, y el juego se dibuja en medio. `PARAMS` es una sola lista de números entre comillas: `WW` (anchura del borde blanco en píxeles de vídeo); `WW WB` (anchura del blanco y luego un borde negro por fuera); `RW GW BW WW` (un color y una anchura de borde personalizados); `RW GW BW WW WB` (lo mismo más una anchura de negro); o `RW GW BW WW RB GB BB WB` (colores y anchuras personalizados para los dos). Un borde que no deja sitio para el juego (el doble de las anchuras del blanco y del negro juntas llega al lado más corto del vídeo), o una anchura negativa, termina el programa con un mensaje. Los anillos se dibujan alrededor de lo que dejaron `--shiftx`, `--shifty` y `--scalefactor`, así que un borde sigue siendo un borde se coloque como se coloque la imagen; véase <<videorect,El rectángulo de vídeo>>.
|
|
|===
|
|
|
|
[#_sound]
|
|
==== Sonido
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `--altaudio=SUFFIX` | Reproduce `<base><SUFFIX>.ogg` junto al vídeo del disco en lugar del audio que lleva dentro, para una edición cuyos otros idiomas vienen en archivos aparte: `--altaudio=-es` junto a `game.m2v` reproduce `game-es.ogg`. Todos los segmentos de un framefile cambian a la vez. Si el archivo no está, sigue sonando el audio propio del juego y se muestra un aviso. La clave `AUDIO_SUFFIX` de `games.dat` hace lo mismo para un juego, y un script lo cambia en marcha con `discAudioSuffix`. Por defecto: ninguno.
|
|
| `-o`, `--audio=TRACK` | Pista de audio por defecto (empezando en cero) para vídeos que tienen varias, como las ediciones en varios idiomas.
|
|
| `-A`, `--audiodelay=MS` | Compensa un audio que se oye `MS` milisegundos más tarde de lo que el motor puede medir (negativo cuando se oye antes), de `-1000` a `1000`. Véase xref:Reference.adoc#audiosync[Sincronización del audio].
|
|
| `-s`, `--nosound` | Silencia todo el audio.
|
|
| `--soundfont=FILE` | La SoundFont (`.sf2`) con la que se sintetizan los archivos MIDI. Singe no incluye ninguna, porque una buena ocupa decenas de megabytes para un formato que casi ningún juego usa. Sin esta opción busca `Singe/soundfont.sf2` -- así un juego empaquetado puede llevar la suya -- y luego en los sitios donde una distribución instala una. La línea `SoundFont:` de la cabecera de la traza dice cuál se usó, o que no se encontró ninguna. Véase xref:Reference.adoc#midi[MIDI]. Por defecto: la búsqueda.
|
|
| `--startsilent` | Arranca en silencio y sigue así hasta la primera entrada de cualquier tipo; luego suena a los volúmenes configurados. Para una recreativa en modo de atracción en una sala tranquila. `--nosound` tiene prioridad sobre ella. Por defecto: desactivada.
|
|
| `-e`, `--volume_nonvldp=PERCENT` | Volumen de los efectos de sonido y del vídeo adicional, de `0` a `100`.
|
|
| `-l`, `--volume_vldp=PERCENT` | Volumen del laserdisc, de `0` a `100`.
|
|
|===
|
|
|
|
[#_input]
|
|
==== Entrada
|
|
|
|
Véase <<controls,Controles>>.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `--absolutes_only` | Conserva solo los ratones que informan de una posición absoluta, que es lo que hace una pistola de luz de verdad y no hace un ratón normal. A ManyMouse no se le puede preguntar qué es un dispositivo, así que un dispositivo cuenta como absoluto en cuanto ha informado de una posición absoluta, y no antes; véase <<mousedevices,Ratones, pistolas y quién decide>>. Hypseus la escribe `-absolutes-only`; aquí el nombre lleva un guion bajo porque una clave de un archivo de ajustes tiene que ser un nombre de Lua. Por defecto: desactivada.
|
|
| `--gamepad_reorder=DIGITS` | Qué mando físico ocupa cada hueco de mando, como posiciones de enumeración contando desde `0`, una para cada hueco por orden: `--gamepad_reorder=10` hace del segundo mando encontrado el jugador uno y del primero el jugador dos. Se escribe con los dígitos seguidos (`3210`) o separados por comas o espacios, como lo escribe Hypseus; una posición repetida se rechaza. Las posiciones no nombradas ocupan los huecos que quedan, en el orden en que las encontró SDL, y una posición sin mando detrás deja su hueco vacío. Por defecto: el orden propio de SDL.
|
|
| `--haptic=STEP` | El paso de vibración más fuerte que puede usar un juego, de `0` a `4`. `0` desactiva la vibración por completo, y un número menor suaviza un juego que pide más: `controllerDoRumble` nunca vibra más fuerte que esto. Por defecto: `4`, que es cualquier paso que pida un juego.
|
|
| `--joymouse=BOOLEAN` | Deja que el stick izquierdo del hueco de mando `0` mueva el cursor del ratón, para un juego de pistola de luz en una recreativa sin ratón. `--joymouse=false` es el `-nojoymouse` de Hypseus, y un script lo fija con `joyMouseEnable()`. Véase <<joymouse,Mover el ratón con un stick>>. Por defecto: `false`, mientras que en Hypseus está activado por defecto -- el `controls.cfg` incluido ya asigna ese stick a las cuatro direcciones.
|
|
| `--js_range=SPEED` | Lo rápido que lo mueve ese stick, de `1` a `20`, en píxeles de vídeo por fotograma con el stick a tope. Por defecto: `5`, como en Hypseus.
|
|
| `--keymapfile=FILENAME` | Lee las asignaciones de controles de este archivo en lugar de buscar `controls.cfg` en los cuatro sitios, para que un front-end sepa con certeza qué asignaciones recibió un juego. Los valores por defecto incorporados siguen aplicándose por debajo, así que un archivo parcial también funciona, y un archivo que no existe termina el programa. Por defecto: la búsqueda en los cuatro sitios, descrita en <<controls,Controles>>.
|
|
| `--manymouse` | Distingue hasta cuatro ratones pida lo que pida el juego, cosa que una recreativa de dos pistolas necesita de un juego que nunca llama él mismo a `mouseSetMode(MOUSE_MANY)`. La elección del usuario prevalece sobre la del juego: `mouseSetMode(MOUSE_SINGLE)` ya no la desactiva. Por defecto: desactivada, y decide el juego.
|
|
| `--mapjoysticks=BOOLEAN` | Escribe una asignación de mando para un dispositivo que SDL no reconoce, para que un encoder de recreativa, un spinner, un volante o un joystick de vuelo se abra como `GAMEPAD_0` a `GAMEPAD_3` igual que cualquier otro. `false` deja sin abrir ese dispositivo, como hacían las versiones anteriores. Véase <<devices,Todo dispositivo es un mando>>. Por defecto: `true`.
|
|
| `-n`, `--nocrosshair` | Pide al juego que no dibuje su propio punto de mira. Los scripts lo ven como `singeWantsCrosshairs()`.
|
|
| `--nogamepad` | Ignora todos los mandos, la contrapartida de `--nomouse`. No se abre ninguno y ningún evento de mando llega al juego, así que un encoder de recreativa atascado no puede pulsar nada. Por defecto: desactivada.
|
|
| `-m`, `--nomouse` | Desactiva por completo la entrada del ratón y de la pistola de luz.
|
|
| `--quitchord=BUTTONS` | Botones del primer mando que salen al mantenerse pulsados a la vez, asigne lo que asigne el juego e incluso cuando ha desactivado su tecla de salida: la forma de salir en una consola portátil sin teclado. Un juego sale al menú desde el que se inició, y el menú cierra Singe. De dos a cuatro nombres de botón de mando de SDL unidos con `+`, como `back+start` (Select y Start); los nombres son `a`, `b`, `x`, `y`, `back`, `guide`, `start`, `leftstick`, `rightstick`, `leftshoulder`, `rightshoulder`, `dpup`, `dpdown`, `dpleft` y `dpright`, tal como los da la asignación del mando, y `--program` escribe en la traza el nombre de cada botón pulsado. Al pulsar uno de los botones de la combinación, se espera un cuarto de segundo al resto antes de hacer lo que hace normalmente, así que Start no inicia un juego desde el menú de camino a salir. Su sitio es el `settings.cfg` de la máquina. Por defecto: ninguno.
|
|
| `--trigger_threshold=PERCENT` | Cuánto tiene que recorrer un gatillo analógico antes de contar como botón, como porcentaje del recorrido completo -- la unidad de Hypseus, cuyo propio valor por defecto es `99.5`. `0` deja los gatillos con `DEAD_ZONE`, que es lo que Singe les ha dado siempre. Gana a `TRIGGER_THRESHOLD` de `controls.cfg`; `DEAD_ZONES` gana a los dos. De `0` a `100`; véase <<deadzones,Zonas muertas y gatillos>>. Por defecto: `0`.
|
|
| `--xratio=FACTOR` | La escala horizontal que un juego de pistola de luz lee con `ratioGetX()` para estirar sus propias coordenadas de pistola en una pantalla cuya forma no coincide con la del vídeo. Singe no hace nada con ella; el juego hace las cuentas, exactamente como en Hypseus. De `0` a `100`, con dos decimales, como la guarda Hypseus. Por defecto: `0`, que todo juego que la lee trata como `1`.
|
|
| `--yratio=FACTOR` | Lo mismo para `ratioGetY()`. Por defecto: `0`.
|
|
|===
|
|
|
|
[#_video_decoding_and_performance]
|
|
==== Decodificación de vídeo y rendimiento
|
|
|
|
Sobre todo para máquinas pequeñas; véase <<handhelds,Consolas portátiles y máquinas pequeñas>>.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `--deinterlace=MODE` | Qué se hace con una imagen entrelazada: `auto` (el valor por defecto) desentrelaza solo los fotogramas que el archivo marca como entrelazados, `on` desentrelaza todos los fotogramas, para un archivo con las marcas mal puestas, y `off` nunca toca la imagen. Un laserdisc contenía campos entrelazados, y un rip que los conservó muestra el efecto peine en una pantalla progresiva; un rip que se desentrelazó al hacerse no necesita nada aquí. Sale una imagen por cada una que entra, así que los números de fotograma nunca se mueven. Por defecto: `auto`.
|
|
| `--monochrome` | Arranca con la imagen del disco en gris. El overlay, las GUI y la escena 3D conservan su color; un script hace lo mismo con `vldpSetMonochrome`, y lo deshace. Por defecto: desactivada.
|
|
| `--scenequality=LEVEL` | Cuánto dibuja la escena 3D: `high`, todo lo que pida un juego, o `low` para una GPU pequeña -- una consola portátil o una de las primeras Raspberry Pi -- que dibuja la escena a la mitad de resolución en cada sentido y prescinde del antialiasing y del bloom pida lo que pida el juego. La imagen 3D es más suave y lo brillante no tiene resplandor, y va mucho más rápido donde el límite era la GPU; el disco, el overlay y las GUI no se tocan. Su sitio es el `settings.cfg` de la máquina más que la línea de comandos de un juego, ya que describe la máquina. Por defecto: `high`.
|
|
| `-H`, `--softwarevideo` | Decodifica el vídeo por software aunque la plataforma ofrezca un decodificador por hardware (VA-API o VDPAU en Linux, el decodificador V4L2 en la Pi, D3D11VA en Windows, VideoToolbox en macOS). Úsala para descartar o confirmar el camino por hardware cuando un vídeo se porta mal; la traza del programa dice qué decodificador se está usando.
|
|
| `--zerocopy=BOOLEAN` | Pasa los fotogramas de vídeo decodificados por hardware directamente a la GPU en lugar de copiarlos a través de la CPU: el decodificador MPP de Rockchip y VA-API en Linux, dibujados con OpenGL ES. Ahorra la mayor parte del coste del vídeo a pantalla completa en una máquina pequeña. Singe vuelve a copiar por su cuenta cuando el controlador no acepta un fotograma, o cuando un juego lee o cambia los píxeles de la imagen, y la traza del programa dice qué está haciendo; `false` hace que copie desde el principio, para descartar o confirmar este camino. Por defecto: `true`.
|
|
|===
|
|
|
|
[#_cabinets_and_front_ends]
|
|
==== Recreativas y front-ends
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `--apiversion` | Escribe en la salida estándar una línea legible por máquina que describe esta compilación y sale, para los front-ends. Véase <<apiversion,La línea de versión>>. No se escribe nada más.
|
|
| `--fvalue=NUMBER` | Un número que el lanzador pasa al juego, que lo lee con `getFValue()`. Singe no hace nada con él. De `0` a `100000`, con tres decimales, como lo guarda Hypseus. Por defecto: `0`.
|
|
| `-h`, `--help` | Muestra el resumen de opciones y sale.
|
|
| `--idleexit=SECONDS` | Sale tras `SECONDS` sin ninguna entrada de ningún tipo -- ninguna tecla, ningún botón, ningún eje de mando, ningún ratón. Para una recreativa en modo de atracción que debe devolver la pantalla. `0` no sale nunca. De `0` a `86400`. Por defecto: `0`.
|
|
| `--no_update_check` | No pregunta nunca al servicio si existe un Singe más reciente. Si no, el menú mira una vez al día y muestra lo que ha encontrado bajo los detalles del juego; la herramienta Engine Update sigue funcionando a mano. Por defecto: desactivada, así que la consulta diaria se hace.
|
|
| `-z`, `--noconsole` | No escribe nada (y no abre ninguna ventana de consola en Windows).
|
|
| `--refresh` | Aparta la carpeta de soporte `Singe` como `old-Singe-<version>`, con el nombre de la versión que la escribió, y escribe una nueva. Para actualizar: un archivo que traía una versión anterior y que esta no trae se queda en la carpeta apartada en lugar de seguir en la que está en uso. No se borra nada, y una segunda ejecución aparta la suya como `old-Singe-<version>-1`. La herramienta Engine Update pasa esta opción al Singe con el que se reinicia.
|
|
|===
|
|
|
|
[#_making_and_testing_games]
|
|
==== Crear y probar juegos
|
|
|
|
Véase <<troubleshooting,Cuando algo sale mal>> para las trazas.
|
|
|
|
[cols="1,2",options="header"]
|
|
|===
|
|
| Opción | Función
|
|
| `--debug[=HOST:PORT]` | Conecta el juego a un depurador que escucha en `HOST:PORT`, normalmente ZeroBrane Studio, que entonces puede detenerlo en puntos de ruptura, ejecutarlo paso a paso y mostrar qué hay en sus variables; consulta xref:Reference.adoc#zerobrane[Depurar en ZeroBrane Studio]. `HOST` es `localhost` si no se indica y `PORT` es `8172`. Si nadie escucha, el juego se juega como siempre una vez que el intento se rinde, en dos segundos como mucho. Por defecto: desactivado.
|
|
| `--deterministic[=MS]` | Solo para pruebas: ignora el tiempo real y ejecuta todo el motor con un reloj virtual que avanza `MS` milisegundos cada fotograma, así que el mismo número de fotograma siempre significa el mismo momento. El disco también sigue el reloj virtual, y sus fotogramas duran el tiempo que valen, y los generadores aleatorios se inicializan con el mismo número, así que una ejecución se repite píxel a píxel. El valor es opcional y es a la vez el paso y la semilla, de `1` a `1000`. Por defecto, si se da sin valor: `15`, el tiempo de fotograma que implica la tasa propia del motor. El ritmo no tiene sentido en este modo, y tampoco el sonido salvo que se dé también `--record`, en cuyo caso se genera al paso de la imagen; véase xref:Reference.adoc#deterministic[Modo de prueba determinista]. Por defecto: desactivada.
|
|
| `-P`, `--pack=DIRECTORY` | Empaqueta el juego de `DIRECTORY` en la base de datos que se nombra tras las opciones y sale. Véase xref:Reference.adoc#singlefile[Juegos de un solo archivo].
|
|
| `-T`, `--patch=GAME.game` | Sustituye archivos del juego empaquetado a partir de la carpeta o la base de datos de parche que se nombra tras las opciones y sale.
|
|
| `--perfsync` | Con `--program`, espera a que la GPU termine cada etapa de un fotograma antes de cronometrar la siguiente, para que las líneas perf digan a qué etapa pertenece el tiempo de la GPU en lugar de dejarlo todo en `present`. Todo va más lento mientras está activada, así que es para medir, no para jugar; véase <<perflines,Leer las líneas perf>>. Por defecto: desactivada.
|
|
| `-p`, `--program` | Escribe una traza de la actividad del motor en la consola y en `trace.txt` en la carpeta de datos. El archivo empieza con una cabecera que describe la máquina; véase xref:Reference.adoc#traceheader[La cabecera de la traza]. Cada cinco segundos dice además adónde se fue el tiempo del fotograma; véase <<perflines,Leer las líneas perf>>.
|
|
| `--record=FILENAME` | Graba toda la ejecución, imagen y sonido, en un MP4 en `FILENAME`, desde el primer fotograma hasta que Singe sale. Con `--deterministic` se conservan todos los fotogramas y el sonido se genera paso a paso junto con la imagen, así que los dos coinciden exactamente y no se oye nada mientras se ejecuta. Véase <<recording,Grabar vídeo>>. Por defecto: desactivada.
|
|
| `-R`, `--reload` | Vigila los archivos de script sueltos del juego y vuelve a ejecutar el juego desde cero cuando uno cambia; `F5` hace lo mismo cuando quieras. Un script que no compila sigue vigilado, así que al guardar el arreglo se recarga. Para trabajar en un juego; véase xref:Reference.adoc#reloading[Recargar mientras trabajas].
|
|
| `-t`, `--trace` | Escribe una traza de cada llamada a la API de Lua, con la línea del script que la hizo, en la consola y en `trace.txt`. El archivo empieza con una cabecera que describe la máquina; véase xref:Reference.adoc#traceheader[La cabecera de la traza].
|
|
| `-U`, `--unpack=GAME.game` | Escribe los archivos del juego empaquetado en la carpeta que se nombra tras las opciones y sale. Se rechaza una base de datos cuyos nombres guardados acabarían fuera de esa carpeta.
|
|
|===
|
|
|
|
Las opciones se pueden dar como `-x 640`, `-x640` o `--xresolution=640`. Los
|
|
valores numéricos se validan; un valor incorrecto muestra el texto de uso y
|
|
sale. Las opciones más nuevas no tienen letra corta; el alfabeto se acabó, y una
|
|
letra elegida al azar no ayudaría a nadie.
|
|
|
|
Todo lo de aquí, salvo las opciones que nombran el juego, nombran una carpeta o
|
|
tienen que actuar antes de que se pueda encontrar un archivo, se puede fijar
|
|
también en un archivo de ajustes, así que una recreativa no necesita un script
|
|
lanzador para cada juego. Véase <<settings,El archivo de ajustes>>.
|
|
|
|
[[apiversion]]
|
|
=== La línea de versión
|
|
|
|
`--apiversion` escribe una línea y sale con el estado `0`:
|
|
|
|
----
|
|
singe version=3.00 protocol=1
|
|
----
|
|
|
|
Esto es un contrato para los front-ends y no cambiará de forma:
|
|
|
|
* La línea termina con un salto de línea y es lo único que se escribe en la
|
|
salida estándar. No se escribe nada más, haya lo que haya en la línea de
|
|
comandos.
|
|
* El primer campo es siempre `singe`.
|
|
* Cada campo posterior es `key=value`, separados por un espacio, sin espacios
|
|
dentro de un campo.
|
|
* `version` es la versión publicada, el mismo número que muestra el rótulo.
|
|
* `protocol` es la versión del formato de esta línea. Solo pasa a ser `2` si
|
|
alguna vez tienen que cambiar las reglas anteriores.
|
|
* Las versiones posteriores pueden añadir campos. Un lector debe ignorar las
|
|
claves que no conoce en lugar de tratarlas como un error.
|
|
|
|
[[cabinet]]
|
|
== Montar una recreativa
|
|
|
|
Las máquinas recreativas necesitan algunas cosas que un ordenador de sobremesa
|
|
no: apartar la imagen de los bordes que el monitor oculta, girarla para una
|
|
pantalla puesta de lado, arte a su alrededor, un borde para una pistola de luz
|
|
Sinden y un marcador. Solo necesitas este capítulo si estás montando una
|
|
recreativa. Configura esto una vez en el `settings.cfg` de la recreativa, o usa
|
|
la herramienta Display del menú (véase
|
|
<<servicetools,Las herramientas de servicio>>) para ajustar la imagen mientras
|
|
la miras.
|
|
|
|
[[videorect]]
|
|
=== El rectángulo de vídeo
|
|
|
|
Todo lo que muestra un juego -- el disco, el overlay, las GUI, la escena 3D y
|
|
las partículas -- se dibuja en un único rectángulo, y un puñado de opciones
|
|
decide dónde está ese rectángulo. Se aplican en este orden:
|
|
|
|
. *La ventana, o el recorte del bezel.* El rectángulo empieza siendo toda la
|
|
ventana. Singe trabaja en las coordenadas propias del vídeo y deja que la
|
|
ventana las encuadre con bandas negras (`--stretch`, en cambio, la llena), así
|
|
que nada de esto depende del tamaño de la ventana. Cuando `--bezel` ha cargado
|
|
un arte que declara un recorte, el rectángulo empieza siendo ese hueco y todo
|
|
lo que sigue coloca la imagen dentro de él; véase <<bezels,Bezels>>.
|
|
. *`--scalefactor`.* El rectángulo se reduce a ese porcentaje de lo que era al
|
|
empezar, alrededor de su propio centro.
|
|
. *`--shiftx` y `--shifty`.* Luego el rectángulo se mueve dentro del espacio que
|
|
dejó la escala, `-100` pegado a un lado y `100` pegado al otro, que es lo que
|
|
significan los propios `-shiftx` y `-shifty` de Hypseus. De ahí se siguen dos
|
|
consecuencias que conviene saber: la imagen nunca se puede sacar de la
|
|
pantalla, y *con `--scalefactor=100` no hay espacio y un desplazamiento no hace
|
|
nada en absoluto*. Para mover la imagen en un monitor mal montado, reduce
|
|
antes la escala: `--scalefactor=90 --shiftx=-100` pone la imagen reducida
|
|
pegada a la izquierda.
|
|
. *`--sindengun`.* El borde se aplica el último, a lo que hayan dejado el
|
|
desplazamiento y la escala. El anillo negro ocupa el borde del rectángulo, el
|
|
anillo blanco va dentro de él y el juego va dentro de los dos, así que un
|
|
borde sigue siendo un borde se haya colocado como se haya colocado la imagen.
|
|
Una escala tan pequeña que no deje sitio para el juego aprieta los dos anillos
|
|
en lugar de tragárselo. Con arte de bezel cargado, el borde va en cambio al
|
|
borde de la ventana y deja la imagen del tamaño que ya tenía; `--sindenedge`
|
|
lo decide en cualquier caso.
|
|
|
|
`--rotate` no forma parte de ese orden. El fotograma se dibuja sin girar y la
|
|
imagen terminada se gira entera en el sentido de las agujas del reloj, así que
|
|
un desplazamiento mueve la imagen a lo largo de los ejes propios del vídeo y
|
|
gira con ella. Un cuarto de vuelta también intercambia la forma de la zona
|
|
presentada, así que una ventana vertical se llena en lugar de quedarse con la
|
|
imagen metida en una franja.
|
|
|
|
Las posiciones del ratón y de la pistola de luz recorren el mismo camino al
|
|
revés: primero se quita la rotación y después la posición se traslada al
|
|
rectángulo, así que un clic cae donde lo ve el jugador con cualquier combinación
|
|
de estas opciones. `vldpGetScale`, `vldpSetScale`, `vldpGetRotate` y
|
|
`vldpSetRotate` permiten a un script mover la escala y la rotación mientras el
|
|
juego se ejecuta; el desplazamiento es un ajuste de la pantalla y no tiene
|
|
llamada de script. Ninguno de ellos es una clave de `games.dat`: igual que
|
|
`--scalefactor`, describen la pantalla del jugador, no el juego.
|
|
|
|
[[bezels]]
|
|
=== Bezels
|
|
|
|
Un bezel (marco decorativo) es el arte que rodea la pantalla de una máquina
|
|
recreativa. Singe dibuja uno a partir de un único archivo de imagen, con la
|
|
imagen del juego en un hueco recortado en él, y puede mostrar un marcador de
|
|
recreativa en el espacio que queda. Lo controlan tres opciones, y siguen la
|
|
convención propia de Hypseus, así que la línea de comandos de una recreativa se
|
|
traslada sin cambios.
|
|
|
|
`--bezel cabinet.png` nombra el arte. Se busca en este orden:
|
|
|
|
. `bezels/cabinet.png` en la carpeta de juegos -- dentro de un `.game`
|
|
empaquetado, su propia copia, así que un juego puede llevar su bezel consigo;
|
|
. `bezels/cabinet.png` en la carpeta de datos, donde puede estar el arte propio
|
|
de un usuario sin tocar una carpeta de juegos de solo lectura.
|
|
|
|
`--bezeldir art/cabinets` sustituye la carpeta `bezels` por la que nombra,
|
|
relativa a la carpeta de juegos o absoluta, y entonces solo se busca en esa
|
|
carpeta. Sirve cualquier formato que lea SDL_image (`.png` es la elección
|
|
sensata, porque la transparencia importa). Un arte que la opción nombra y que
|
|
Singe no encuentra termina el programa en lugar de ejecutarse sin él.
|
|
|
|
El arte se dibuja sobre toda la ventana, tenga la forma que tenga cualquiera de
|
|
los dos, así que se estira con la ventana exactamente igual que la imagen. Dale
|
|
la relación de aspecto con la que esperas jugar.
|
|
|
|
[#_the_cutout]
|
|
==== El recorte
|
|
|
|
Junto al archivo de imagen, y con su mismo nombre, un archivo complementario dice
|
|
dónde va la imagen del juego: `bezels/cabinet.png` lo describe
|
|
`bezels/cabinet.cfg`. Es un archivo Lua, como `controls.cfg`, y fija una tabla
|
|
en los *propios píxeles* del arte:
|
|
|
|
[source,lua]
|
|
----
|
|
-- El hueco de cabinet.png en el que se dibuja la imagen, en los propios píxeles del arte.
|
|
CUTOUT = { x = 200, y = 120, width = 800, height = 500 }
|
|
----
|
|
|
|
Los cuatro campos son obligatorios y el rectángulo debe quedar dentro del arte;
|
|
un archivo complementario que no se puede ejecutar, o que nombra un rectángulo
|
|
fuera de la imagen, termina el programa con un mensaje. Como los números son los
|
|
del propio arte, siguen siendo correctos con cualquier tamaño de ventana: la
|
|
imagen y el hueco se escalan juntos.
|
|
|
|
Con un recorte, la imagen se dibuja en ese hueco -- estirada hasta llenarlo, así
|
|
que el hueco decide la forma de la imagen -- y `--scalefactor`, `--shiftx` y
|
|
`--shifty` funcionan entonces *dentro* de él, reduciendo y empujando la imagen
|
|
en el hueco. Sin archivo complementario, la imagen conserva toda la ventana,
|
|
exactamente igual que sin bezel, y esas tres opciones la colocan como siempre.
|
|
Véase <<videorect,El rectángulo de vídeo>>.
|
|
|
|
El propio hueco debería ser transparente en la imagen. Singe dibuja el arte
|
|
detrás de la imagen por defecto, así que un centro opaco simplemente quedaría
|
|
tapado, pero `--bezelflip` pone el arte delante y entonces solo su transparencia
|
|
deja ver el juego.
|
|
|
|
[#_draw_order]
|
|
==== Orden de dibujo
|
|
|
|
Sin `--bezelflip`, el arte es lo primero del fotograma: la imagen, el overlay,
|
|
las GUI, la escena 3D y las partículas se dibujan todas encima. Con
|
|
`--bezelflip`, el arte se dibuja en cambio delante de la imagen, que es el orden
|
|
que usa Hypseus para sus propios bezels, así que un marco con bordes suaves o
|
|
con forma se superpone bien a la imagen.
|
|
|
|
Un script decide qué pasa con el overlay en ese caso:
|
|
xref:Reference.adoc#setoverlayontop[`setOverlayOnTop(true)`] dibuja el overlay y las GUI por encima
|
|
del arte, y `false` (el valor por defecto, y el de Hypseus) deja el arte encima
|
|
de ellos. Con el arte detrás de la imagen, el ajuste no cambia nada, porque todo
|
|
está ya por encima.
|
|
xref:Reference.adoc#mainbezelloaded[`mainBezelLoaded()`] le dice a un script si hay arte cargado
|
|
y le da el identificador del arte, el mismo número del que informa Hypseus, para
|
|
que un juego escrito para un bezel concreto pueda reconocerlo.
|
|
|
|
Las GUI en espacio de pantalla y el panel de puntuación siempre se dibujan por
|
|
encima del arte, ya que su razón de ser es ir sobre él.
|
|
|
|
[#_the_sinden_border]
|
|
==== El borde Sinden
|
|
|
|
Una pistola de luz Sinden vigila la pantalla buscando un borde brillante. Con
|
|
arte de bezel cargado, ese borde va en el *borde de la ventana*, no alrededor de
|
|
la imagen, porque la cámara de la pistola ve toda la pantalla, así que ahí es
|
|
donde lo pone `--sindengun` en cuanto se carga un bezel. Ahí se dibuja como dos
|
|
anillos, después de todo lo demás, así que el arte que hay entre el borde y la
|
|
imagen sigue visible y nada pinta encima del anillo blanco. Sin bezel, el borde
|
|
va alrededor de la imagen, como siempre, y la reduce.
|
|
|
|
`--sindenedge video` o `--sindenedge window` anula esa elección en cualquiera de
|
|
los dos sentidos: una recreativa de pistola cuyo arte es solo un marco fino puede
|
|
seguir queriendo el borde alrededor de la imagen, y una recreativa sin ningún
|
|
arte puede quererlo en el borde de la pantalla.
|
|
|
|
[#_the_score_panel]
|
|
==== El panel de puntuación
|
|
|
|
Dieciséis de los juegos Singe de Hypseus pueden manejar un marcador de
|
|
recreativa: los créditos, y una puntuación y un contador de vidas para cada uno
|
|
de dos jugadores. En Singe, ese marcador es el documento RmlUi
|
|
`Singe/scoreBezel.rml`, con el estilo de `Singe/scoreBezel.rcss`, ambos escritos
|
|
junto a los demás archivos de soporte. Como todo lo que hay en la carpeta
|
|
`Singe`, se escriben de nuevo en cada arranque, así que editarlos no cambia nada
|
|
por mucho tiempo: un juego que quiere otro aspecto trae sus propias copias,
|
|
`scoreBezel.rml` junto a su script enlazando una hoja de estilo propia, y Singe
|
|
usa esas en su lugar. El estilo incluido imita un display de siete segmentos:
|
|
cada indicador muestra sus dígitos débilmente iluminados detrás del valor
|
|
actual, como hace un display de verdad.
|
|
|
|
El panel está *desactivado* hasta que un juego lo pide con
|
|
xref:Reference.adoc#scorebezelenable[`scoreBezelEnable(true)`], que es también como lo distribuye
|
|
Hypseus, así que un juego que nunca lo pide se comporta exactamente como antes y
|
|
dibuja su propio marcador con sprites. xref:Reference.adoc#scorebezelgetstate[`scoreBezelGetState()`] es la
|
|
pregunta que todo juego así hace primero.
|
|
|
|
Dónde va se decide por ti: el panel ocupa la más alta de las dos franjas que la
|
|
imagen deja encima y debajo -- el espacio que suele dejar el recorte de un bezel
|
|
-- centrado respecto a la imagen, y se coloca a lo largo de la parte inferior de
|
|
la imagen cuando ninguna de las dos franjas es lo bastante alta para contenerlo.
|
|
Se dibuja como una GUI en espacio de pantalla, así que un juego puede poner sus
|
|
propias GUI sobre el arte, junto a él, con
|
|
xref:Reference.adoc#guidrawscreen[`guiDrawScreen`].
|
|
|
|
El `scoreBezelEnable` de Hypseus admite un segundo argumento que elige entre sus
|
|
cinco implementaciones de marcador. Singe tiene una, así que el argumento se
|
|
acepta y se ignora.
|
|
|
|
[[handhelds]]
|
|
== Consolas portátiles y máquinas pequeñas
|
|
|
|
Singe funciona en la Raspberry Pi y en consolas portátiles ARM baratas como la
|
|
R36S. Allí funcionan los mismos juegos que en un ordenador de sobremesa, pero una
|
|
máquina pequeña necesita un poco de ayuda para ejecutarlos bien.
|
|
|
|
[#_what_a_small_machine_needs]
|
|
=== Lo que necesita una máquina pequeña
|
|
|
|
Los sprites, el texto, el sonido y el vídeo funcionan en todas partes. La escena
|
|
3D y el aspecto vistoso del menú necesitan un chip gráfico con Vulkan u OpenGL
|
|
ES 3.1.
|
|
|
|
* Una Raspberry Pi 4 o posterior tiene las dos cosas, así que todo funciona. Una
|
|
Pi 3 solo tiene OpenGL ES 2.0, que no basta para el 3D. Aun así, ejecuta los
|
|
juegos 2D.
|
|
* La mayoría de las consolas portátiles, incluida la R36S, tienen un chip
|
|
gráfico Mali con OpenGL ES 3.1, así que el 3D también funciona en ellas.
|
|
* En una máquina sin ninguno de los dos, el menú usa un aspecto más sencillo que
|
|
no los necesita.
|
|
|
|
La primera vez que ejecutas un juego 3D, Singe compila sus shaders, lo que puede
|
|
tardar unos segundos en una máquina pequeña. Se guardan en la carpeta `Singe`
|
|
dentro de la carpeta de datos, así que esto solo pasa una vez.
|
|
|
|
[#_settings_for_a_small_machine]
|
|
=== Ajustes para una máquina pequeña
|
|
|
|
Pon esto en el `settings.cfg` que está junto al binario de Singe para que todos
|
|
los juegos lo usen:
|
|
|
|
`scenequality = "low"`::
|
|
Dibuja la escena 3D a la mitad de tamaño, sin antialiasing ni bloom. El 3D se ve
|
|
un poco más suave, pero va mucho más rápido. El vídeo, los sprites y los menús
|
|
no se ven afectados.
|
|
|
|
`zerocopy = true`::
|
|
Ya es el valor por defecto. El vídeo va del decodificador por hardware
|
|
directamente al chip gráfico sin que la CPU lo copie. Esto es lo que permite a
|
|
una consola portátil reproducir vídeo de laserdisc a toda velocidad. Desactívalo
|
|
solo si un vídeo se porta mal y quieres descartarlo.
|
|
|
|
`quitchord = "back+start"`::
|
|
Las consolas portátiles no tienen tecla Esc. Mantener pulsados Select y Start
|
|
te saca del juego al menú, y del menú a tu sistema, esté como esté configurado
|
|
el juego.
|
|
|
|
[#_the_r36s_and_arkos]
|
|
=== La R36S y ArkOS
|
|
|
|
La R36S y las consolas portátiles parecidas con ArkOS usan la compilación
|
|
`aarch64` de Linux de Singe. Pon el binario de Singe, su carpeta `Singe`,
|
|
`Menu.sh` y tus juegos en una misma carpeta, como `/roms/singe`. Ejecuta
|
|
`Menu.sh` una vez para que Singe pueda crear sus archivos de soporte.
|
|
|
|
Para iniciar Singe desde el menú Ports, añade a `/roms/ports` un script como el
|
|
de abajo. Estas consolas portátiles tardan en subir la velocidad de su
|
|
procesador y de su chip gráfico, así que el script los pone a toda velocidad
|
|
mientras Singe se ejecuta y los deja como estaban cuando sale.
|
|
|
|
[source,bash]
|
|
----
|
|
#!/bin/bash
|
|
# /roms/ports/Singe.sh: Singe en el menú Ports.
|
|
SINGE_DIR=/roms/singe
|
|
|
|
[ "$(id -u)" -eq 0 ] && ESUDO="" || ESUDO="sudo"
|
|
GOVERNORS=()
|
|
for g in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor /sys/class/devfreq/*/governor; do
|
|
[ -f "$g" ] || continue
|
|
GOVERNORS+=("$g:$(cat "$g")")
|
|
echo performance | $ESUDO tee "$g" > /dev/null 2>&1
|
|
done
|
|
restore() {
|
|
for entry in "${GOVERNORS[@]}"; do
|
|
echo "${entry##*:}" | $ESUDO tee "${entry%:*}" > /dev/null 2>&1
|
|
done
|
|
}
|
|
trap restore EXIT
|
|
|
|
cd "$SINGE_DIR" || exit 1
|
|
./Menu.sh "$@"
|
|
----
|
|
|
|
ArkOS no informa a los juegos de los botones Select y Start, así que la
|
|
combinación de salida no funcionará hasta que añadas este `gamecontrollerdb.txt`
|
|
junto al binario de Singe (véase <<gamecontrollerdb,gamecontrollerdb.txt>>):
|
|
|
|
----
|
|
1900bb3e4b4800000011000000010000,GO-Super Gamepad,a:b0,b:b1,x:b2,y:b3,back:b12,start:b13,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpdown:b9,dpleft:b10,dpright:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
|
|
----
|
|
|
|
Si un botón no hace lo que esperas, ejecuta Singe una vez con `--program` y
|
|
púlsalo. La traza muestra el nombre de cada botón que pulsas, o su número si la
|
|
asignación de arriba no lo incluye.
|
|
|
|
Por último, añade un `controls.cfg` junto al binario de Singe. Este pone la
|
|
moneda y Start en Select y Start, y mantiene los menús de prueba y de servicio
|
|
de un juego fuera de los botones frontales, donde algunos juegos los ponen.
|
|
|
|
[source,lua]
|
|
----
|
|
INPUT_1P_COIN = { SCANCODE.MAIN_5, SCANCODE.C, GAMEPAD_0.BUTTON_BACK }
|
|
INPUT_1P_START = { SCANCODE.MAIN_1, GAMEPAD_0.BUTTON_START }
|
|
INPUT_PAUSE = { SCANCODE.P }
|
|
INPUT_SCREENSHOT = { SCANCODE.F12, SCANCODE.F11 }
|
|
INPUT_SERVICE = { SCANCODE.MAIN_9 }
|
|
INPUT_TEST_MODE = { SCANCODE.F2 }
|
|
----
|
|
|
|
Este archivo gana al que incluye un juego (véase
|
|
<<configorder,Dónde se leen los archivos de configuración>>). La pausa y la
|
|
captura de pantalla pasan al teclado porque Singe normalmente las pone en Start
|
|
y Select.
|
|
|
|
[[troubleshooting]]
|
|
== Cuando algo sale mal
|
|
|
|
[#_the_trace]
|
|
=== La traza
|
|
|
|
Ejecuta Singe con `--program` (o `-p`) para ver lo que está haciendo. Todo se
|
|
escribe en la consola y se guarda en `trace.txt` en la carpeta de datos del
|
|
juego. Si informas de un problema, incluye el `trace.txt` de una ejecución con
|
|
`--program`. `--trace` (o `-t`) registra además cada llamada a Lua que hace un
|
|
juego, lo que sobre todo es útil al escribir un juego.
|
|
|
|
Si Singe se cuelga en Linux o macOS, escribe dónde se colgó en la consola y en
|
|
`trace.txt`.
|
|
|
|
`trace.txt` solo tiene los mensajes propios de Singe. Los mensajes del sistema de
|
|
sonido, del decodificador de vídeo y del controlador gráfico solo van a la
|
|
consola. Cuando el problema pueda estar ahí, guarda también la consola. En
|
|
Linux:
|
|
|
|
----
|
|
./Menu.sh --program &> singe.log
|
|
----
|
|
|
|
[[perflines]]
|
|
=== Leer las líneas perf
|
|
|
|
Con `--program`, cada cinco segundos la traza dice adónde se fue el tiempo, como
|
|
promedios por vuelta del bucle de fotogramas:
|
|
|
|
----
|
|
Perf: 58.9 frames/s shown, 353 loops; per loop 13.1 ms (worst 82.3): disc 1.1, script 0.1, scene 0.0, gui 0.4, overlay 0.0, compose 0.0, present 11.4, other 0.1
|
|
Perf script: per loop 0.1 ms of Lua and 0.0 in engine calls it made; 0.0 in engine calls altogether: overlayClear 0.01 (0.8 calls), discGetFrame 0.00 (0.8 calls)
|
|
Video 3 perf: 23.8 frames/s decoded; per frame 0.5 ms, of which read back 0.0, convert 0.0
|
|
----
|
|
|
|
* `disc` -- avanzar el vídeo del laserdisc y poner su fotograma en la GPU.
|
|
* `script` -- el `onOverlayUpdate` del juego, que la línea `Perf script` divide
|
|
entre el propio Lua y las llamadas al motor que hizo, de la más costosa a la
|
|
menos.
|
|
* `scene` -- dibujar la escena 3D.
|
|
* `gui` -- maquetar y dibujar los documentos de la GUI.
|
|
* `overlay` -- enviar a la GPU lo que cambió en el overlay.
|
|
* `compose` -- solo con `--perfsync`: la GPU dibujando juntos la imagen, el
|
|
overlay y las GUI.
|
|
* `present` -- mostrar el fotograma, lo que incluye esperar al siguiente
|
|
refresco de la pantalla.
|
|
* `other` -- todo lo demás: entrada, sonido, física y el resto.
|
|
|
|
La línea propia de un vídeo dice lo rápido que se decodifica y cuánto de cada
|
|
fotograma se fue en copiarlo de vuelta desde el decodificador por hardware y en
|
|
convertir sus colores; cero en ambos significa que sus fotogramas van a la GPU
|
|
sin copiarse.
|
|
|
|
La GPU trabaja por detrás de la CPU, así que sin `--perfsync` su tiempo cae allí
|
|
donde la CPU tenga que esperarla a continuación, que suele ser `present`. Un
|
|
`present` grande a la tasa completa de la pantalla es solo la espera del
|
|
refresco; un `present` grande por debajo de ella significa que la GPU está
|
|
ocupada. `--perfsync` hace que cada etapa espere a la GPU antes de que empiece
|
|
la siguiente, así que `scene`, `gui`, `overlay` y `compose` incluyen su tiempo de
|
|
GPU y a `present` le queda la espera del refresco. La tasa de fotogramas baja
|
|
mientras está activada, porque la CPU y la GPU ya no trabajan a la vez; compara
|
|
las etapas entre sí, no con la tasa de fotogramas.
|
|
|
|
[#_a_button_does_nothing]
|
|
=== Un botón no hace nada
|
|
|
|
Abre la herramienta Input Test del menú (véase <<servicetools,Las herramientas de servicio>>)
|
|
y pulsa el botón. Si la herramienta lo ve, el juego lo está ignorando, así que
|
|
revisa el `controls.cfg` del juego. Si la herramienta no lo ve, revisa tu propio
|
|
`controls.cfg`, o la asignación de tu mando en `gamecontrollerdb.txt`.
|
|
Ejecutar con `--program` muestra cada botón según lo pulsas.
|
|
|
|
[#_sound_and_picture_are_out_of_sync]
|
|
=== El sonido y la imagen no van sincronizados
|
|
|
|
Algunos televisores, receptores y altavoces inalámbricos retrasan el sonido. Usa
|
|
la herramienta Audio Delay del menú para medir el retardo. Singe lo recuerda para
|
|
todos los juegos. Véase xref:Reference.adoc#audiosync[Sincronización del audio]
|
|
para más detalles.
|
|
|
|
Si el sonido se entrecorta o va a trompicones, consulta las preguntas frecuentes.
|
|
|
|
[#_frequently_asked_questions]
|
|
== Preguntas frecuentes
|
|
|
|
*¿Por qué se llama Singe?*
|
|
|
|
Singe es el nombre del dragón de Dragon's Lair. Como Singe (el programa) empezó
|
|
como complemento de Daphne (la princesa de Dragon's Lair), se mantuvo el tema de
|
|
Dragon's Lair.
|
|
|
|
*¿Qué diferencia hay entre Daphne, Singe, Hypseus y Singe 3.xx?*
|
|
|
|
Daphne es un auténtico emulador de juegos de laserdisc que puede ejecutar un
|
|
puñado de juegos de láser clásicos. Daphne/Singe (Singe 1.xx) es la versión
|
|
original de Singe, que era un complemento del emulador Daphne -- distribuido al
|
|
principio como una DLL de juego para Daphne, y combinado más tarde en un solo
|
|
binario sin las funciones de emulación de Daphne. Hypseus-Singe es un fork
|
|
mejorado de Daphne con compatibilidad con Singe 1.xx y parte de Singe 2.xx.
|
|
Singe 2.xx es una actualización totalmente nueva, hecha desde cero, del Singe
|
|
original, y Singe 3.xx se basa en ella y añade 3D, física y mucho más. En
|
|
resumen, si quieres fidelidad, usa Daphne o Hypseus si pueden emular el juego
|
|
que quieres. Si es un juego de Singe, usa Singe, o prueba Hypseus.
|
|
|
|
*¿Por qué no deberíamos llamarlo «emulador»?*
|
|
|
|
Los emuladores usan el software real o las ROM del juego original y se hacen
|
|
pasar por la máquina en la que ese juego debía ejecutarse. Desde el punto de
|
|
vista del juego, todo sigue como siempre. Singe, en cambio, exige que cada juego
|
|
se reimplemente (se adapte) para funcionar en Singe. El resultado final puede
|
|
ser muy parecido, pero cómo funciona es totalmente distinto.
|
|
|
|
*¿Puedo ejecutar juegos de Singe 1.xx y 2.xx en Singe 3.xx?*
|
|
|
|
Sí, probablemente. Casi todo lo de Singe 1.xx se ha convertido y mejorado para
|
|
las versiones más nuevas de Singe, y la mayoría de los juegos de Singe 2.xx
|
|
funcionan tal cual. Los juegos que usan las funciones de sprites antiguas pueden
|
|
necesitar un pequeño cambio; véase
|
|
xref:Reference.adoc#migrating[Migración desde Singe 2.10].
|
|
|
|
*¿Necesito un juego de laserdisc para usar Singe?*
|
|
|
|
No. Los juegos no necesitan ningún disco. Pueden usar sprites, vídeo, 3D y
|
|
cualquier otra cosa que ofrezca Singe. Véase
|
|
xref:Reference.adoc#withoutadisc[Juegos sin disco].
|
|
|
|
*¿Por qué no aparece en el menú el juego que acabo de instalar?*
|
|
|
|
Quien empaquetó el juego no incluyó un archivo `games.dat` como es debido.
|
|
|
|
*¿Por qué va lento el vídeo HD?*
|
|
|
|
Ya no debería. Singe usa ahora tu tarjeta gráfica para decodificar el vídeo
|
|
cuando tu sistema lo permite, incluso en la Raspberry Pi y en muchas consolas
|
|
portátiles. Si el vídeo HD sigue yendo lento, puede que tu sistema no tenga
|
|
decodificación de vídeo por hardware, y entonces el vídeo de alta definición
|
|
necesita mucha CPU. Ejecutar con `--program` muestra qué decodificador está
|
|
usando Singe.
|
|
|
|
*¿Por qué se entrecorta el audio en Windows?*
|
|
|
|
Los usuarios han descubierto que la mayoría de los problemas de audio y de
|
|
tirones de Singe tienen que ver con el controlador de audio instalado -- sobre
|
|
todo en dispositivos basados en Realtek. Prueba a actualizar los controladores de
|
|
sonido o a cambiar al controlador genérico Windows HD Audio. Desactiva el sonido
|
|
envolvente -- usa estéreo, no 5.1 ni 7.1. Si tus controladores no te dejan usar
|
|
estéreo, puedes usar Virtual Audio Cable para arreglarlo:
|
|
|
|
. Instala VB-CABLE (https://vb-audio.com/Cable/).
|
|
. Ve a la configuración de sonido de Windows (haz clic con el botón derecho en el
|
|
icono de sonido de la barra de tareas, luego en *Sonidos* y luego en
|
|
*Reproducción*).
|
|
. Haz clic con el botón derecho en el dispositivo *Cable Input* y elige
|
|
*Establecer como dispositivo predeterminado*. (Perderás temporalmente la salida
|
|
de sonido actual.)
|
|
. Ve a la pestaña *Grabación*.
|
|
. Haz clic con el botón derecho en *Cable Output*, luego en *Propiedades*, luego
|
|
en *Escuchar* y, por último, activa *Escuchar este dispositivo*. En la lista
|
|
desplegable, elige el dispositivo con el que escuchas de verdad.
|
|
. Deberías volver a tener sonido. Abre Singe y el audio funcionará, y sin
|
|
retrasos.
|
|
|
|
*¿Funciona el 3D en una Raspberry Pi o en una consola portátil?*
|
|
|
|
En una Raspberry Pi 4 o posterior, sí. Tienen tanto un controlador Vulkan como
|
|
OpenGL ES 3.1, y Singe usa el que encuentre. La Pi 3 solo tiene OpenGL ES 2.0,
|
|
que no puede expresar el skinning ni los morph targets de la escena, así que
|
|
ejecuta los juegos 2D (física 2D incluida) exactamente como antes y rechaza la
|
|
primera llamada 3D. La Pi 4 es el mínimo para cualquier juego que use el
|
|
capítulo de escenas 3D. Lo mismo vale para las consolas portátiles baratas: una
|
|
Mali-G31 o G610 tiene el ES 3.1 que necesita la escena, tenga o no Vulkan. Véase
|
|
<<handhelds,Consolas portátiles y máquinas pequeñas>>.
|
|
|
|
*¿Por qué se entrecorta el audio en la Raspberry Pi?*
|
|
|
|
Raspberry Pi OS usa ahora Pipewire como backend de audio por defecto. Cambiar a
|
|
PulseAudio parece arreglar el problema:
|
|
|
|
. Ejecuta `sudo raspi-config` desde una ventana de terminal.
|
|
. Selecciona *Advanced Options*.
|
|
. Selecciona *Audio Config*.
|
|
. Selecciona *PulseAudio*.
|
|
. Pulsa kbd:[Tab], selecciona *Ok* y deja que se reinicie.
|
|
|
|
|
|
[#_making_games]
|
|
== Crear juegos
|
|
|
|
Este manual trata de ejecutar Singe: instalarlo, instalar juegos, montar una
|
|
recreativa y el menú. Crear juegos se trata en otros dos libros, que son una
|
|
descarga opcional desde el mismo sitio que Singe en lugar de formar parte de él,
|
|
ya que juntos ocupan más que el motor.
|
|
|
|
* La *Referencia de Singe* trata todo lo que puede hacer un juego: el modelo de
|
|
programación, la carpeta del juego, empaquetar un juego en un solo archivo y
|
|
cada función que ofrece el motor, con sus argumentos, sus valores de retorno y
|
|
un ejemplo.
|
|
* *Aprende a programar con Singe* enseña a programar desde cero, en treinta y
|
|
una lecciones, a alguien que nunca ha escrito código. Viene con los scripts y
|
|
el pequeño kit de arte que usan las lecciones.
|
|
|
|
La descarga contiene los dos libros en PDF y HTML, los archivos de las lecciones
|
|
y la licencia. Los tres libros están escritos en inglés, francés, italiano,
|
|
alemán y español, y la descarga viene en cada uno de ellos: elige la de tu
|
|
idioma. Las traducciones de este manual ya están en la carpeta `Singe`, a su
|
|
lado. Forge, la herramienta de autoría que crea un juego a partir de una
|
|
descripción en lugar de a partir de código, es un proyecto aparte con su propia
|
|
descarga y su propio libro.
|
|
|