Skip to content
 
 

Repository files navigation

Sonic Battle Text Editor Plus

Sonic Battle Text Editor Plus es un editor de textos para Sonic Battle (Game Boy Advance) pensado para traducir el juego. Permite abrir una ROM, editar sus diálogos y menús, y guardar los cambios directamente en el archivo.

Este proyecto es un fork de Sonic Battle Text Editor, creado por Sahlaysta. Gracias de corazon por todo el trabajo del proyecto original.

Sobre esa base, esta versión "Plus" agrega herramientas de localización, gestión de espacio en la ROM, operaciones masivas por idioma, sección o capítulo, detección automática de líneas que se desbordan, un Story Mode con hablantes identificados e interfaz bilingüe (inglés y español latinoamericano).

Pantalla principal de Sonic Battle Text Editor Plus


Tabla de contenidos

Para traducir

  1. Descripción general
  2. Comunidad y soporte
  3. Requisitos
  4. Inicio rápido
  5. Funciones y cómo usarlas
  6. Flujo de trabajo recomendado
  7. Atajos de teclado
  8. Limitaciones y consideraciones

Para desarrollar o empaquetar

  1. Desarrollo y empaquetado
  2. Qué aporta respecto al original
  3. Arquitectura técnica
  4. Pruebas
  5. Pendiente (TODO)
  6. Licencias
  7. Créditos

Descripción general

Sonic Battle guarda sus diálogos y menús como cadenas de texto codificadas dentro de la ROM, junto con tablas de punteros organizadas por idioma y sección. Editar esos textos a mano implica lidiar con ese formato binario; el editor original resuelve eso permitiendo abrir una ROM US/EU/JP, editar el texto, previsualizarlo con los glifos reales del juego y guardar los cambios.

Plus conserva ese núcleo y agrega lo necesario para traducir el juego completo con más facilidad. Idiomas como el español suelen ocupar más espacio que el inglés o el japonés, así que el editor ayuda a liberar espacio en la ROM, controlar el ancho de línea y trabajar por bloques (idioma, sección o capítulo).

Soporta las tres regiones oficiales del juego: USA (BSBE), Europa (BSBP) y Japón (BSBJ). También puede abrir ROMs modificadas, aunque su compatibilidad depende de los cambios que contengan.


Comunidad y soporte

  • Descargas: revisa las releases del proyecto para obtener las versiones publicadas.
  • Errores y compatibilidad: abre un issue indicando la versión del editor, el sistema operativo, la región de la ROM, los pasos para reproducir el problema y el mensaje de error completo. No adjuntes ROMs ni contenido protegido.
  • Contribuciones: revisa CONTRIBUTING.md antes de proponer cambios.
  • Historial de cambios: consulta CHANGELOG.md.
  • Preparación de releases: consulta RELEASING.md.

Requisitos

Para usar la versión empaquetada (Windows)

  • Windows 10/11 x64.
  • La carpeta portable completa (o el ZIP de release). No hace falta instalar Java: la distribución incluye su propio runtime.
  • Una ROM de Sonic Battle (.gba) de región US, EU o JP. Se recomiendan dumps limpios No-Intro de las regiones admitidas: BSBE (USA), BSBP (Europa) o BSBJ (Japón). Algunas ROMs modificadas también funcionan, pero no se garantiza su compatibilidad.

Para compilar o ejecutar el JAR

  • JDK 17 o superior (el bytecode compila para JVM 17). En Windows conviene fijar JAVA_HOME al JDK, no al JRE antiguo que pueda estar en el PATH.
  • Maven 3.6+.
  • Un sistema con soporte para Swing (Windows, macOS o Linux).

Importante: este repositorio no incluye ROMs. Debes aportar tu propia copia legal del juego.

Antes de editar: conserva siempre una ROM limpia sin modificar y trabaja sobre una copia. El editor guarda los cambios directamente en la ROM abierta; usa Archivo --> Guardar como para crear una ROM de trabajo o una nueva versión antes de aplicar cambios importantes.


Inicio rápido

  1. Conserva una ROM limpia y crea una copia de trabajo, por ejemplo Sonic Battle - trabajo.gba.
  2. Abre la aplicación (SonicBattleTextEditorPlus.exe si usas la distribución con runtime, o el JAR con Java 17).
  3. Ve a Archivo --> Abrir (o Ctrl/Cmd+O) y elige tu copia de trabajo .gba.
  4. En el árbol, navega por idioma --> sección (o capítulo de Story Mode) --> línea. Al seleccionar un texto editable aparece el panel de edición en la parte inferior.
  5. Edita el texto en ese panel. Si quieres ver cómo se verá en el juego: Ver --> Vista previa de texto, o clic derecho --> Mostrar vista previa (se abre a escala 4X).
  6. Si el texto crece más de lo que cabía originalmente, revisa Herramientas --> Espacio libre y, si hace falta, borra idiomas que no vayas a usar o expande la ROM a 32 MiB.
  7. Usa Herramientas --> Desbordes de línea para localizar líneas demasiado anchas. Corrígelas una por una o con Corregir todos.
  8. Guarda con Archivo --> Guardar (Ctrl/Cmd+S). Para conservar hitos de tu avance, usa Archivo --> Guardar como con un nombre nuevo. Si el editor advierte que el texto puede no caber, libera espacio o expande la ROM antes de insistir.

Si la interfaz se abre en inglés y prefieres español: Ver --> Idioma --> Español (Latinoamérica).


Funciones y cómo usarlas

Idioma de la interfaz

Menú: Ver --> Idioma --> English / Español (Latinoamérica)

Los textos de la interfaz salen de src/main/resources/i18n/messages_en.properties y messages_es.properties. Cambiar el idioma actualiza al instante menús, diálogos y etiquetas.

Archivos recientes y búsqueda

  • Archivo --> Abrir recientes conserva accesos a las últimas ROMs abiertas. La lista se guarda en las preferencias del usuario.
  • Editar --> Buscar (Ctrl/Cmd+F) busca en todos los textos de la ROM. La búsqueda no distingue mayúsculas de minúsculas ni espacios entre caracteres; si introduces solo un número, también encuentra las entradas cuyo índice de línea coincide. Usa las flechas o Enter para navegar a un resultado.
  • Navegar --> Subir/Bajar una fila y Expandir/contraer fila permiten recorrer el árbol sin usar el ratón.

Apariencia y panel de edición

  • Ver --> Tema oscuro alterna entre los temas claro y oscuro.
  • Ver --> Aumentar/Disminuir/Restablecer tamaño del texto cambia el tamaño de fuente del editor. También puedes usar Ctrl/Cmd + rueda.
  • Ver --> Ajuste automático del panel de texto adapta la altura del panel al contenido seleccionado.
  • Ver --> Restablecer altura del panel de texto devuelve el divisor a su posición predeterminada.

El tema, el tamaño del texto y la configuración del panel se conservan entre sesiones.

Borrar idioma, sección, capítulo o texto

Menú: Herramientas --> Borrar idioma/sección seleccionado

  1. Selecciona en el árbol un idioma completo, una sección o un capítulo de Story Mode.
  2. Confirma la acción. Los textos seleccionados quedan vacíos.
  3. Al guardar, el programa recupera el espacio de esos bloques e invalida los punteros correspondientes.

Es útil si vas a traducir a un solo idioma (por ejemplo, solo español): vaciar alemán, francés o italiano libera espacio para cadenas más largas.

La misma acción está disponible en el menú contextual del árbol. Sobre una línea editable, el menú contextual añade además Mostrar vista previa, Copiar como HEX, copiar desde otro idioma y exportar/importar JSON. En el nodo raíz de la ROM se omite el borrado completo para evitar una eliminación accidental de todos los textos.

Copiar desde otro idioma

Menú: Herramientas --> Copiar desde otro idioma

  1. Selecciona el idioma o sección de destino.
  2. Elige el idioma de origen en el diálogo.
  3. Confirma. La copia respeta la sección y el índice de línea.

Sirve para partir de una traducción existente (por ejemplo, del inglés) y editar encima, en vez de empezar de cero.

Corregir colores [WHITE]

Menú: Herramientas --> Corregir colores [WHITE]

Corrige etiquetas de color ambiguas en el idioma, sección o capítulo seleccionado. Los [WHITE] de cierre pasan a [BLACK]; los de apertura toman el color de la entrada inglesa equivalente. Al corregir inglés, o cuando el inglés no ofrece una referencia útil, se usa el japonés como respaldo.

La aplicación muestra cuántos textos se modificarán y omite los que no puede alinear con seguridad. Esta operación masiva vacía el historial de deshacer.

Eliminar espacios finales

Menú: Herramientas --> Eliminar espacios finales

Elimina los espacios situados justo antes de un salto de línea o al final de un texto. Esos espacios no se ven en el juego, pero ocupan bytes en la ROM. La acción puede aplicarse a una línea, un idioma, una sección o un capítulo, informa cuántos textos cambiarán y vacía el historial de deshacer después de la confirmación.

Salto automático de línea

Menú: Herramientas --> Salto automático de línea

Recalcula los saltos de línea (\n) según los anchos reales de los glifos del juego (SonicBattleGlyphWidths). Respeta las palabras completas y no corta etiquetas de color ([RED], etc.) ni códigos de control hexadecimales ([FBFF], …).

El límite de ancho por línea depende de la sección: 216 px en diálogos de Story Mode sin flecha (y el resto de secciones), 203 px en la línea par de un cuadro que continúa, 123 px en descripciones de tarjeta (EMERL_CARD_DESCRIPTIONS), y 207 px en nombres de habilidad (EMERL_SKILLS, lista de habilidades; estos además se limitan a 1 línea, el autoajuste no inserta \n en nombres). Una línea con flecha que termina en la elipsis centrada conserva el techo de 216 px. Los espacios al final de línea no cuentan para el overflow. La separación entre glifos es de 1 px (la misma métrica que usa la vista previa).

Expandir ROM a 32 MiB

Menú: Herramientas --> Expandir ROM a 32 MiB

Las ROMs oficiales de Sonic Battle pesan 16 MiB. Esta acción añade 16 MiB de 0xFF al final del archivo, lo que permite que el guardado coloque texto nuevo usando punteros del banco 0x09 (la mitad superior de la imagen expandida).

  • Emuladores y la mayoría de flashcarts aceptan ROMs de 32 MiB.
  • La expansión solo ocurre al ejecutar esta acción; guardar por sí solo no la activa.
  • Es necesario guardar después de expandir: si no guardas, el cambio no queda escrito en la ROM.

Liberar stubs de texto de la versión JP (FR/DE/ES/IT)

Menú: Herramientas --> Liberar stubs JP (FR/DE/ES/IT)

Se aplica únicamente a la ROM japonesa (BSBJ) y recupera aproximadamente 843 KiB. Los slots de menú de Français, Deutsch, Español e Italiano pasan a apuntar al texto en inglés. El Story Mode en japonés e inglés no se modifica.

Espacio libre

Menú: Herramientas --> Espacio libre (el propio ítem del menú muestra además un contador aproximado)

Muestra:

  • Espacio libre usable y el bloque libre más grande disponible.
  • Número de regiones libres.
  • Capacidad todavía no materializada al final de la imagen.
  • Cadenas pendientes de reubicar, bytes que ocuparán y bytes que se liberarán al guardar.

Si el espacio total parece suficiente pero el guardado falla de todos modos, suele tratarse de fragmentación: el string más grande no cabe en el hueco más grande disponible. Expandir a 32 MiB o vaciar idiomas que no uses suele resolverlo.

Errores de codificación

Menú: Herramientas --> Errores

Lista las cadenas que no pudieron decodificarse o codificarse correctamente, o que contienen caracteres sin glifo en el juego. El ítem del menú muestra el conteo actual (Errores (n)).

Desbordes de línea

Menú: Herramientas --> Desbordes de línea También disponible en: Buscar --> modo desbordes (con botones Corregir / Corregir todos)

Detecta líneas cuyo ancho de glifos supera el límite aplicable (216 px en diálogos sin flecha, 203 px en filas con flecha de continuación, 123 px en descripciones y 207 px en nombres de habilidad). La elipsis centrada no colisiona con la flecha y permite 216 px. En descripciones también marca textos con más de 7 líneas; en nombres, más de 1 línea. Los espacios al final de línea no cuentan. En el árbol, estas líneas aparecen marcadas con un indicador y un tooltip.

Flujo típico:

  1. Abre Desbordes de línea.
  2. Revísalas una a una, o pulsa Corregir todos para aplicar el mismo algoritmo de ajuste automático.
  3. Algunas palabras son más anchas que el cuadro y no se pueden partir, esas hay que acortarlas a mano.

Story Mode: capítulos y hablantes

Al abrir la ROM:

  • Agrupa el Story Mode en capítulos (C1 - Sonic, C2 - Tails, …, Journal).

  • Extrae los hablantes recorriendo los scripts de eventos (opcodes de diálogo) y los muestra encima del editor:

    Hablante: Sonic (línea 12)

Cuando el extractor no puede identificar un hablante, o detecta ambigüedad, la etiqueta lo indica. Esto suele pasar cuando el script no fija un personaje o su imagen para esa frase: puede tratarse de texto de narrador, un aviso o el diálogo de un personaje que no está en pantalla.

Ver --> Mostrar hablante probable completa visualmente las líneas sin hablante detectado con una atribución curada. La etiqueta marca expresamente que se trata de un hablante probable. Esta ayuda no modifica la ROM ni sustituye un hablante que sí haya sido identificado; su valor se guarda en las preferencias.

En las secciones que no son diálogos (menús, nombres de áreas, habilidades, etc.) no hay hablante: la etiqueta muestra en su lugar la sección y el índice de línea:

Menú de opciones | Línea 0

Así, cada string tiene un identificador claro sin depender de navegar el árbol.

Exportar / Importar JSON

Menú: Archivo --> Exportar textos a JSON / Importar textos desde JSON

Alcance

Si tienes seleccionado un idioma, sección o capítulo en el árbol, la exportación e importación se limitan a ese subconjunto. Así puedes, por ejemplo, traducir solo el Story Mode en español sin arrastrar el resto de la ROM.

Formato de Story Mode

Cada línea de diálogo se exporta así:

{
  "speaker": "Sonic", "text": "¡Vamos, Tails!\n¡No hay tiempo que perder!"
}
  • speaker: metadato de referencia (quién habla). Cuando la extracción no identifica uno, la exportación usa la atribución probable disponible. No se reescribe en la ROM al importar.
  • text: el único campo que se aplica al importar.

Los campos speakerId y lineIndex no se exportan: provienen de los scripts de eventos de la ROM y editarlos desde JSON no sería seguro.

En secciones que no son Story Mode, las entradas pueden ser cadenas simples (como en el original) u objetos con un campo "text".

La importación valida el tipo de ROM, las claves, los duplicados y los valores nulos incompatibles antes de aplicar cualquier cambio. Si algo no encaja, cancela la operación y muestra la lista de errores.

Mensajes de error mejorados

Cuando falla abrir, guardar o procesar un JSON, el editor muestra:

  1. Un resumen breve del problema.
  2. Por qué ocurrió.
  3. Posibles soluciones, numeradas.
  4. Un enlace a Ver detalles técnicos con el stack trace o el mensaje original.

Preferencias

Ruta: ~/.sbtep/prefs.json

Incluye el tamaño, posición y estado maximizado de la ventana; tema; archivos recientes; último directorio de cada selector de archivos; idioma de la interfaz; tamaño de fuente; altura y ajuste automático del panel de texto; y la opción de hablante probable. Si el archivo no existe, la aplicación usa sus valores predeterminados y lo crea al guardar preferencias.

Panel de edición y vista previa

  • El panel inferior (etiqueta + cuadro editable) solo aparece cuando seleccionas un texto editable en el árbol. Si seleccionas un idioma, sección o capítulo, o cierras la ROM, el panel se oculta y el árbol ocupa toda el área.
  • Ver --> Ajuste automático del panel de texto adapta la altura al contenido; si lo desactivas, puedes mover el divisor manualmente.
  • Ver --> Restablecer altura del panel de texto devuelve el divisor a su altura predeterminada (el estado, incluido si está oculto, se recuerda y se aplica al volver a abrir una línea).
  • Ver --> Vista previa de texto abre la ventana de glifos a escala 4X (puedes cambiarla en Más opciones --> Escala).
  • Clic derecho sobre una línea editable --> Mostrar vista previa abre la misma ventana.

Generar sprites de nombres de habilidad

Menú: Herramientas --> Generar sprites de nombres de habilidad

Genera las hojas BMP de los nombres de habilidad de Emerl a partir de los textos de EMERL_SKILLS. Esta herramienta no escribe los gráficos en la ROM: solo prepara los archivos para que los importes después con una herramienta gráfica compatible, como YY-CHR.

La fuente de título permite generar nombres en los cinco idiomas europeos que admite el juego: español, inglés, francés, alemán e italiano. Incluye las letras acentuadas, ligaduras y signos de puntuación habituales de esos idiomas, tanto si se escriben en mayúscula como en minúscula.

  1. Edita los nombres que necesites en la sección Nombre de habilidades. La herramienta vuelve a renderizar solo las entradas modificadas; el resto conserva los sprites originales de plantilla.
  2. Abre Generar sprites de nombres de habilidad y elige inglés o japonés, si la ROM ofrece ambos.
  3. Corrige los nombres que usen caracteres sin glifo en la fuente de título. Además de A–Z, números, espacio y Lv, se admiten las letras y los signos descritos debajo.
  4. Si un nombre supera 64 px, la aplicación ofrece truncarlo. El truncado afecta solo al BMP generado; el texto en la ROM no cambia.
  5. Se generan diez hojas, de CHR000.bmp a CHR009.bmp, en la carpeta img-text/ junto al JAR en uso (en la distribución de Windows, puede quedar dentro de app/). Importa esos BMP en la ROM con tu herramienta gráfica y verifica el resultado dentro del juego.

Caracteres europeos adicionales admitidos:

  • Español: Á, É, Í, Ó, Ú, Ü, Ñ, ¡ y ¿.
  • Francés: À, Â, Æ, Ç, È, É, Ê, Ë, Î, Ï, Ô, Œ, Ù, Û, Ü y Ÿ.
  • Alemán: Ä, Ö, Ü y ß.
  • Italiano: vocales con acento grave, agudo o circunflejo disponibles en la codificación europea del juego.
  • Signos generales: ., -, ?, !, ', , ,, :, ;, &, /, +, (, ), ", y º.

Los caracteres acentuados escritos en minúscula utilizan el mismo diseño de título que su variante mayúscula. Las equivalencias œ/Œ, ÿ/Ÿ y ß/ también comparten glifo visual.

Esta generación no reemplaza el proceso de edición gráfica ni crea un parche de ROM. Conserva una copia de trabajo antes de importar los BMP y prueba los nombres directamente en el juego.


Flujo de trabajo recomendado

Traducir (ROM US o EU)

  1. Abre una copia de trabajo de la ROM y, si prefieres, cambia la interfaz a español.
  2. Guarda una versión inicial con Archivo --> Guardar como antes de aplicar operaciones masivas.
  3. En el árbol, selecciona el idioma.
  4. (Opcional) Borra los idiomas que no vayas a usar (alemán, francés, …) para ganar espacio.
  5. Si prevés mucho crecimiento de texto: Expandir ROM a 32 MiB y guarda.
  6. Exporta a JSON el idioma o el Story Mode completo.
  7. Traduce fuera del editor (o edita directamente dentro, con la vista previa abierta).
  8. Importa el JSON sobre la misma selección.
  9. Ejecuta Desbordes de línea --> Corregir todos y revisa a mano lo que quede pendiente.
  10. Revisa Espacio libre y guarda. Usa Guardar como para marcar cada hito de tu traducción.

Traducir Story Mode con hablantes visibles

  1. Español --> Story Mode --> capítulo (por ejemplo, C1 - Sonic).
  2. Selecciona líneas: la etiqueta de hablante da contexto al diálogo; en menús y otras secciones verás Sección | Línea N.
  3. Abre la vista previa (menú Ver o clic derecho) si quieres ver el cuadro de texto a 4X mientras editas.
  4. Si trabajas con un equipo de traductores, exporta solo ese capítulo.

ROM japonesa con poco espacio

  1. Abre la ROM BSBJ.
  2. Ejecuta Liberar stubs JP (FR/DE/ES/IT) y guarda.
  3. Si aún falta espacio, expande la ROM a 32 MiB.
  4. Continúa con la traducción del idioma objetivo.

Atajos de teclado

Atajo (Windows/Linux) macOS Acción
Ctrl+O Cmd+O Abrir
Ctrl+S Cmd+S Guardar
Ctrl+Shift+S Cmd+Shift+S Guardar como
Ctrl+W Cmd+W Cerrar
Ctrl+Z / Ctrl+Y Atajos de plataforma Deshacer / Rehacer
Ctrl+↑ / Ctrl+↓ Cmd+↑ / Cmd+↓ Subir / bajar fila
Ctrl+Enter Cmd+Enter Expandir / contraer fila
Ctrl+F Cmd+F Buscar
Ctrl++ Cmd++ Aumentar tamaño del texto
Ctrl+- Cmd+- Disminuir tamaño del texto
Ctrl + rueda Cmd + rueda Aumentar / disminuir tamaño del texto
F1 F1 Acerca de

Las acciones del menú Herramientas no tienen atajos propios; se usan desde el menú o el menú contextual del árbol. La vista previa tampoco tiene atajo dedicado: usa Ver --> Vista previa de texto o clic derecho --> Mostrar vista previa.


Limitaciones y consideraciones

  • No incluye ROMs. Ver Requisitos.
  • Compatibilidad de ROM. El soporte se centra en dumps limpios de Sonic Battle USA (BSBE), Europa (BSBP) y Japón (BSBJ). Es posible abrir una ROM parcheada, una traducción existente o un mod, pero su compatibilidad no está garantizada. Conserva siempre una copia limpia para poder volver a empezar si hace falta.
  • Cambios en archivos. Guardar modifica directamente la ROM abierta. El guardado atómico reduce el riesgo de dejar un archivo a medio escribir, pero no reemplaza una copia de seguridad ni permite deshacer un cambio ya guardado.
  • El JAR requiere Java 17 o superior. Java 8 u 11 no pueden abrirlo. En Windows, la distribución con runtime evita este problema; ver Compilación y ejecución.
  • La distribución con runtime actual es para Windows x64. En macOS o Linux puedes usar el JAR con un JDK 17 instalado; todavía no hay una app-image empaquetada para esas plataformas en este repositorio.
  • La expansión a 32 MiB está en fase de pruebas y pensada para emulación y flashcarts. No es compatible con cartuchos originales de 16 MiB, y puede ser incompatible con algunos parches o mods.
  • Liberar stubs JP elimina los idiomas europeos de la ROM japonesa (quedan solo japonés e inglés).
  • Sprites de nombres de habilidad. La generación de BMP trabaja con los textos de EMERL_SKILLS en inglés o japonés. Solo prepara las hojas gráficas: la importación de esos BMP a la ROM se hace manualmente con una herramienta externa. Cada nombre de sprite tiene un límite de 64 px, distinto del límite de texto de la lista de habilidades.
  • Operaciones masivas. Borrar, copiar, corregir colores, eliminar espacios finales o aplicar el salto de línea automático vacía el historial de deshacer; el diálogo lo advierte antes de confirmar.
  • Las palabras más anchas que el cuadro de texto no se pueden partir con el ajuste automático; hay que acortarlas a mano.
  • Fragmentación de espacio libre. Un total alto de espacio libre no garantiza que el string más grande quepa; revisa el "bloque libre más grande" en Espacio libre.
  • Hablantes. Se obtienen de los scripts de diálogo. Algunas líneas pueden aparecer sin hablante o como ambiguas, cuando el juego no fija un personaje o imagen para esa frase. En secciones que no son diálogo, la etiqueta usa el nombre de la sección en vez del hablante.
  • Charset del juego. No todos los caracteres Unicode existen como glifo; los que no están soportados generan errores de codificación.
  • Límite de tamaño. El juego trabaja sobre una ROM de 16 MiB. Si no liberas idiomas ni expandes a 32 MiB, puede faltar espacio para textos muy largos.

Qué aporta respecto al original

Área Original (SonicBattleTextEditor-master) Plus
Idioma de la UI Solo inglés Inglés y español (Latinoamérica), con preferencia persistente
Guardado Reescribe todas las cadenas en el espacio original Solo las cadenas modificadas; escritura in situ o reubicación en espacio libre
Espacio ROM Error genérico si no cabe Aviso previo, informe de espacio libre, expansión explícita a 32 MiB y liberación de stubs JP
Story Mode Lista plana de líneas Capítulos y etiqueta de hablante
Desbordes de línea No se detectan Lista, resaltado y corrección automática
JSON Exportación/importación global de cadenas planas Operaciones por selección, con objetos speaker + text para Story Mode
Herramientas Sin operaciones de localización agrupadas Borrar, copiar, corregir colores y espacios finales, autoajuste, JSON, espacio libre, errores y desbordes
Preferencias Archivo junto al JAR ~/.sbtep/prefs.json
Experiencia de edición Interfaz básica Búsqueda mejorada, archivos recientes, tema, tamaño de texto, panel adaptable y mensajes de error guiados
Sprites de habilidades Plantillas originales sin soporte de traducción ampliado Generación multilingüe con letras acentuadas y puntuación para español, inglés, francés, alemán e italiano
Pruebas y documentación Estructura mínima Tests unitarios, pruebas de integración opcionales y documentación oficial autosuficiente

Las funciones de uso diario están descritas en Funciones y cómo usarlas. Los detalles de implementación necesarios para comprender y contribuir al programa están resumidos a continuación.


Arquitectura técnica

El proyecto original concentra buena parte de su lógica en pocos archivos de la GUI y un método SBTEROM.save monolítico. En Plus, la arquitectura es más modular: el objetivo es aislar fallas y poder extender la capa de ROM sin acoplarla a Swing.

GUI (fachada)
├── GUIFileIO          --> abrir / guardar / JSON (en segundo plano)
├── GUIRomTools        --> expandir a 32 MiB, liberar stubs JP
├── GUIEditorBulkOps   --> borrar, copiar, colores, espacios y auto-wrap
├── GUISearch          --> búsqueda, errores y desbordes
├── GUITextPreview     --> previsualización con glifos del juego
├── GUIStrings         --> i18n EN/ES
├── GUIErrorMessages   --> mensajes de error amigables
└── GUIEditor          --> árbol, hablantes, contadores, overflow

ROM (independiente de Swing)
├── SBTEROMStringWriter      --> guardado selectivo
├── SBTEROMFreeSpaceFinder   --> espacio libre / append
├── SBTEROMPointerCodec      --> bancos 0x08 / 0x09
├── SBTEROMReservedRegions   --> zonas no tocables
├── SBTEROMJpStubRegions     --> stubs de idioma JP
└── story/*                  --> capítulos y hablantes

Stack

  • Kotlin 1.9.0, JVM target 17
  • Swing + FlatLaf 3.2 (+ extras)
  • Jackson 2.17.2 (streaming de JSON)
  • trove4j 3.0.3
  • sahlaysta.swing 2.5 (repositorio Maven local en lib/)

Módulos Kotlin relevantes (Plus)

Paquete / archivo Rol
gui/GUIStrings.kt Carga de properties i18n y MessageFormat
gui/GUIFileIO.kt I/O de ROM y JSON en segundo plano, escritura atómica
gui/GUIRomTools.kt Expandir a 32 MiB, liberar stubs JP
gui/GUIEditorBulkOps.kt Borrar, copiar, corregir colores, limpiar espacios y ajustar líneas
gui/GUISearch.kt Buscar por texto o índice y recorrer errores/desbordes
gui/GUITextPreview.kt Vista previa de texto con los glifos de cada región
gui/SonicBattleGlyphWidths.kt Anchos de glifo: 216 (diálogo) / 123 (descripciones) / 207 (nombres de lista); helpers por sección
gui/SonicBattleAutoLineBreak.kt Ajuste automático de línea (en nombres no inserta \n)
gui/SonicBattleLineOverflow.kt Detección de overflow (ancho y tope de líneas en tarjetas/nombres)
gui/SonicBattleTrailingSpaces.kt Detección y eliminación de espacios finales invisibles
gui/GUIJSONExport.kt Exportación/importación de JSON, total o por subconjunto
rom/SBTEROMStringWriter.kt Guardado selectivo: dirty / in situ / relocate
rom/SBTEROMFreeSpaceFinder.kt Búsqueda de huecos seguros y ampliación dentro de la capacidad actual
rom/SBTEROMPointerCodec.kt Codificación de punteros GBA
rom/SBTEROMPointerLiteralIndex.kt Evita bases que colisionan con literales en código
rom/SBTEROMReservedRegions.kt Rangos reservados por región
rom/SBTEROMKnownFreeSpace.kt Colas conocidas de espacio libre
rom/SBTEROMJpStubRegions.kt Regiones de stubs multi-idioma JP
rom/SBTEIntRangeSet.kt Sustituto ligero de TreeRangeSet de Guava
rom/story/* Capítulos y extracción de hablantes

Modelo de blob (cambio clave)

En el original, un blob mutable era esencialmente { binary, pointerAddress }.

En Plus:

SBTEMutableBlob
  binary
  pointerAddress
  dataAddress      // dónde viven los bytes ahora
  allocatedSize    // hueco reservado (permite pad 0xFF in situ)
  dirty            // si debe reescribirse al guardar

Guardado selectivo (algoritmo resumido)

  1. Filtrar los blobs marcados como dirty.
  2. Si el nuevo binario cabe en allocatedSize --> escribir in situ y rellenar el resto con 0xFF.
  3. Si creció (o no tiene dirección asignada) --> liberar el espacio antiguo, buscar una base segura en los huecos disponibles (se prueban primero las regiones más grandes) o agregarlo al final dentro de la capacidad de la imagen.
  4. Las cadenas que no están marcadas como dirty conservan sus bytes y punteros intactos.

Preferencias y recursos

  • Preferencias de usuario: ~/.sbtep/prefs.json
  • Charset y glifos: src/main/resources/sonicbattlecharset.json, sonicbattleglyphs_{us,eu,jp}.json
  • i18n: src/main/resources/i18n/messages_*.properties
  • Atribuciones probables de hablantes: src/main/resources/atribuciones-hablantes-null.json
  • Plantillas para nombres de habilidad: src/main/resources/skill-title-glyphs/ y skill-name-sprite-sheets/. Los glifos de título son BMP indexados de 8 bits, conservan la paleta original de 13 colores y tienen una altura máxima de 5 píxeles.

Extender la UI (i18n)

  1. Añade la clave en messages_en.properties y messages_es.properties.
  2. Úsala con GUIStrings.t("clave") o GUIStrings.t("clave", arg0, …).
  3. Si agregas un ítem de menú nuevo, regístralo en GUIMenuBar.applyLocalizedTexts().

Extender la capa ROM

La lógica de escritura no debe depender de Swing. Prefiere agregar APIs en rom/; si la GUI necesita orquestar esa lógica, hazlo en GUIFileIO, GUIRomTools o GUIEditorBulkOps.


Pruebas

Ubicación: src/test/kotlin/sahlaysta/sbtep5/…

# Solo unitarios (Surefire)
mvn test

# Unitarios + pruebas de integración (*IT.kt) con Failsafe
mvn verify

ROMs para las pruebas de integración (opcionales)

Las clases *RealRomIT.kt y SBTEStorySpeakerRealRomIT se omiten automáticamente si no encuentran dumps disponibles. Para ejecutarlas:

  1. Crea una carpeta roms/ en la raíz del proyecto y copia allí dumps No-Intro .gba cuyos nombres incluyan USA, Europe o Japan, por ejemplo:
    • roms/Sonic Battle (USA) (En,Ja,Fr,De,Es,It).gba
    • roms/Sonic Battle (Europe) (En,Ja,Fr,De,Es,It).gba
    • roms/Sonic Battle (Japan) (En,Ja).gba
  2. O bien, define variables de entorno o propiedades del sistema:
    • SBTE_US_ROM / -Dsbte.us.rom=…
    • SBTE_EU_ROM / -Dsbte.eu.rom=…
    • SBTE_JP_ROM / -Dsbte.jp.rom=…

Las ROMs no se incluyen en el repositorio; debes aportar tu propia copia legal.

Cobertura orientativa:

  • Presencia de recursos (charset, glyphs, i18n).
  • Carga de recursos de charset, glifos e internacionalización.
  • Factory de JSON y forma de la importación.
  • Expansión de ROM / espacio libre.
  • Regiones de stubs JP.
  • Pruebas de integración opcionales: carga de ROM US/EU/JP, espacio libre, stubs, conteo de hablantes en Story Mode (2229 / 70).

JaCoCo genera el informe de cobertura en la fase test.


Desarrollo y empaquetado

Esta sección es para quienes van a compilar, depurar o preparar una distribución del proyecto. Si solo quieres usar la aplicación en Windows, la carpeta portable incluye su propio runtime y no requiere instalar Java.

Por qué Java 17

El proyecto compila para Java 17 LTS, la versión usada también para el empaquetado con jpackage. Esto permite distribuir la aplicación de Windows con un runtime incluido. El JAR no funciona con Java 8 ni 11.

Compilación y ejecución

Ejecuta estos comandos desde la raíz del repositorio, con JDK 17+ y Maven 3.6+ instalados:

java -version          # debe mostrar 17 o superior
mvn test               # ejecuta las pruebas unitarias
mvn clean package      # genera el JAR con dependencias en target/
mvn exec:java          # ejecuta la aplicación durante el desarrollo

Para generar la distribución portable de Windows x64 necesitas, además, un JDK que incluya jpackage y tener JAVA_HOME apuntando a ese JDK:

mvn -Pdist package -DskipTests

El resultado queda en dist/windows-x64/SonicBattleTextEditorPlus/, y el ZIP correspondiente en dist/. Para regenerar una distribución a partir de un JAR ya existente, usa scripts/package-runtime.ps1, que acepta los parámetros -Version, -MainJar, -SkipZip y -ProjectRoot.

Para comprender la separación entre la interfaz y la lógica de ROM, el modelo de guardado y los puntos de extensión, consulta Arquitectura técnica.


Pendiente (TODO)

Ideas y funciones que todavía no están implementadas:

  • Cambiar la fuente del texto del programa por la misma que usa el juego, para visualizar mejor cómo quedarán los textos mientras se escriben.
  • Agregar la posibilidad de añadir nuevas líneas de texto a los diálogos, para expandir o reordenar el contenido con más libertad.
  • Cambiar los retratos de personajes en los diálogos, de modo que la cara mostrada coincida con quien habla cuando se reescriben o reordenan las líneas.
  • Extraer todas las imágenes del juego que contienen texto, para editarlas fuera del editor e importarlas de vuelta a la ROM.
  • Ampliar el programa con herramientas para otros recursos gráficos:
    • Sprites de los personajes
    • Retratos (portraits)
    • Paletas de colores
    • Sprites usados para el texto y la interfaz
  • Extraer los archivos de voz del juego, para poder importar audios modificados que reemplacen a los originales.

Licencias

El proyecto base y este fork se distribuyen bajo licencia MIT; consulta LICENSE.txt. Las dependencias y sus licencias declaradas están listadas en THIRD_PARTY_NOTICES.md. El diálogo Ayuda --> Acerca de, dentro de la aplicación, incluye los textos de licencia distribuidos con ella.

Quien prepare una distribución debe comprobar que el ZIP incluya los avisos y textos de licencia exigidos por cada dependencia; la lista de verificación está en RELEASING.md.

Sonic Battle es marca de SEGA. Este proyecto no está afiliado a SEGA.


Créditos

  • sahlaysta (porog): autor del Sonic Battle Text Editor original.
  • Shary: mejoras de localización, gestión de espacio en ROM, visualización, i18n, JSON y herramientas construidas sobre esa base.
  • Comunidades SBHAX y SBHS: investigación histórica sobre offsets, scripts y formato de texto de Sonic Battle.
  • Comunidad CRT Gamers Chile: gracias por el apoyo al proyecto.
  • Comunidad Sonic en Chile, el evento Sonic Fanstars y el grupo de cosplayers Team Sonic Chile: gracias por su apoyo y entusiasmo.

Las pautas para contribuir están en CONTRIBUTING.md.

About

Sonic Battle Text Editor Plus

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages