.gui do TA: Kingdoms: árvores de widgets separadas por espaços
Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub
O TA: Kingdoms desenhava o menu principal, o lobby, o HUD da partida e as caixas de diálogo a partir de arquivos
.gui, um formato peculiar de descrição de widgets separado por espaços em branco. Apesar de parecer com os arquivos de interface do próprio TA (também.gui), o formato do TA:K tem outra estrutura e os dois não são intercambiáveis.
Note
Por enquanto o kbot não tem um subcomando para o .gui do TA:K: o formato
está documentado aqui para que a referência fique completa e para orientar
ferramentas futuras. Ainda assim, dá para examinar esses arquivos à mão;
eles são texto ASCII puro.
O que você está vendo
Um arquivo .gui é uma sequência plana de widgets. O widget de
cabeçalho do arquivo declara o número total de widgets e os metadados
globais (imagem de fundo, teclas de atalho); cada widget depois dele descreve
um único elemento da interface.
Um widget típico tem esta cara:
4 1 ← widget type (4 = button), unused flag (always 1)
1 ← unused (always 1 except in headers)
2 196 79 95 20 1 0 0 0 ← bounds: type, X, Y, W, H, flags…
3 0 0 0 0 ← colour: type, R, G, B, A
1 0 0 ← unused (always 1 0 0)
1 14 hattfont11.gaf ← font: type, len, name
12 PlayerColor 2 12 ← control name + state count
3 ← number of gaf frames that follow
1 17 singlemachine.gaf 14 SingleMachine0 0 18 ← disabled frame
1 17 singlemachine.gaf 14 SingleMachine0 1 18 ← pressed frame
1 17 singlemachine.gaf 14 SingleMachine0 2 18 ← released frame
3 ← number of strings that follow
2 0 0 2 0 4 Exit 2 0 4 Exit 3 ← state strings (disabled, pressed, up)
1 7 Default
1 12 skirmish.wav ← sound played when activated
1 7 Default
2 0 16 Play the Machine ← tooltip / mouseover help
0 ← number of child widgets
Os tokens são separados por espaços em branco. O primeiro token de cada widget é o ID do tipo de widget; tudo o que vem depois segue um esquema próprio de cada tipo.
Strings prefixadas pelo comprimento
O truque mais importante do formato: toda string vem precedida pelo seu comprimento em caracteres, como um token inteiro. Isso quer dizer que as strings podem conter espaços, mas o analisador precisa ler primeiro o comprimento.
1 14 MainScreen.gaf
^ ^^ ^^^^^^^^^^^^^^
│ │ │
│ │ └─ the string itself (14 characters)
│ └─ length
└─ string-flavour prefix (1 = literal string)
Uma string nula/vazia é 1 0 0 (prefixo, comprimento zero, e os dados vazios
são "a string vazia"). Os prefixos 1/0 repetidos são muito fáceis de ler
errado se você simplesmente quebrar o texto nos espaços e começar a contar: é
preciso ler em sequência, na ordem dos widgets.
Important
Não adianta procurar com grep "o terceiro botão" num arquivo .gui: a
estrutura é sequencial, não endereçável. Os editores feitos para este
formato são analisadores sequenciais.
Tipos de widget
IDs de tipo de widget observados:
| ID | Widget | Observações |
|---|---|---|
2 |
Cabeçalho / formulário | Primeiro widget do arquivo. Traz o fundo, as teclas de atalho e o número de filhos. |
4 |
Botão | 3 estados (desativado / pressionado / solto). |
5 |
Caixa de seleção | Matriz de 5 estados (desativada, desmarcada-pressionada, marcada-pressionada, desmarcada-solta, marcada-solta). |
9 |
Moldura | Contêiner invisível; só agrupa widgets visualmente. |
12 |
Contêiner da barra de rolagem | Delimita o controle deslizante e seus botões de aumentar/diminuir. |
14 |
Botão da barra de rolagem (aumentar / diminuir / cursor) | Três destes vêm depois de cada 12. |
15 |
Caixa de lista | Preenchida durante a execução; os modelos estão quase vazios. |
17 |
Botão de opção | 3 estados. |
18 |
Botão de vários estados | Botão que alterna entre N estados (por exemplo, o seletor de "dificuldade da IA"). |
19 |
Imagem + rótulo | O widget combinado do TA:K para arte estática + legenda. |
Cada tipo tem um esquema fixo para os tokens que vêm depois do ID do tipo. O esquema canônico obtido por engenharia reversa por Dark Rain está preservado nos materiais de referência que acompanham este repositório.
Forma genérica de um widget
[TYPE] 1
1
2 [X] [Y] [W] [H] 1 0 0 0
3 [colour: A R G B]
1 0 0
1 [font: length name]
[control-name length] [name] 2 3
[N]
1 [len] [gaf] [len] [seq] [frame] 9 × N
[N]
2 0 0 2 [string set] × N entries inline
1 7 Default
1 [len] [activate.wav]
1 7 Default
2 0 [help length] [help text]
[child-count]
Para cada tipo de widget, o tamanho de [N] e a estrutura do conjunto de
strings variam; os esquemas nos materiais de referência documentam cada um.
Códigos de alinhamento
Dentro do conjunto de strings:
| Código | Alinhamento |
|---|---|
0 |
Centralizado |
1 |
À esquerda |
2 |
À direita |
Num widget de um único estado você vê, por exemplo, 2 0 6 Player; num botão
de 3 estados você vê os três estados concatenados, por exemplo
2 0 0 2 0 6 Player 2 3 6 Play2r 3.
Exemplo comentado: menu principal
2 1
2 0 0 640 480 1 1 0 0
3 255 255 255 255
1 0 0
1 0
8 MainMenu 1 2
2
1 15 TitleScreen.tsf 7 JPGTest 0 9
1 15 TitleScreen.tsf 7 JPGTest 1 9
2
2 0 0 2 0 0 2
1 0
1 0
2 0 24 #Enter#Play#Esc#Previous
6
Lendo de cima para baixo:
2 1: widget do tipo 2 (cabeçalho), flag 1.2 0 0 640 480 1 1 0 0: limites na origem, 640×480, mais os quatro tokens de flags.3 255 255 255 255: entrada de cor branca opaca.8 MainMenu 1 2: nome de controle "MainMenu" (8 caracteres), seguido de1 2.- As duas entradas
TitleScreen.tsf JPGTestsão a imagem de fundo (duas referências duplicadas; o motor quer as duas). 2 0 24 #Enter#Play#Esc#Previous: atalhos de teclado:Enteraciona o controle chamado "Play",Escaciona "Previous".6: o formulário contém 6 widgets filhos, que vêm logo em seguida.
Fundos TSF e GAF
O widget de cabeçalho aceita duas fontes de fundo:
.tsf: a forma em texto de uma animação truecolor do TA:K, que o carregador da interface lê diretamente. Para um menu estático, é só um invólucro fino de um JPG (o exemploTitleScreen.tsfenvolveTitleScreen.jpg), mas o mesmo formato descreve animações completas de vários quadros. Veja TAF / TSF para a estrutura binária e a de texto, que o kbot analisa e reproduz em ida e volta..gaf: a animação padrão do TA: Kingdoms. O cabeçalho referencia uma sequência dentro do GAF, e o motor a reproduz como fundo.
Nos dois casos, o formato exige que a entrada da imagem apareça duas vezes seguidas; só a segunda cópia é de fato renderizada. É uma peculiaridade conhecida.
Armadilhas
Warning
Um arquivo .gui não tem checksum nem marcadores de recuperação. Um
único token de número de filhos contado errado desloca, sem aviso, todos os
widgets seguintes. O motor carrega o arquivo (ele não valida a estrutura),
mas você vai ver widgets no lugar errado, nomes de controle que não são
encontrados ou botões fantasmas.
- Os espaços em branco só servem para separar tokens. Os arquivos lançados pela Cavedog usam tanto espaços quanto tabulações; trate qualquer sequência de espaços em branco como um único separador.
- O número de filhos precisa ser exato. Um widget de moldura (tipo 9)
que termina com
4toma os quatro widgets de nível superior seguintes como filhos. Erre o número e o resto do formulário se desfaz. - Os widgets de caixa de lista e de barra de rolagem são, na prática, modelos vazios nos arquivos originais: o motor os preenche durante a execução a partir do estado do script. Não adianta tentar preenchê-los de forma estática.
- A opção de linha de comando
-disablecavedogverificationdo TA:K é obrigatória para carregar a maioria dos arquivos.guide mods. Sem ela, o motor rejeita qualquer arquivo cujo hash não bata com uma lista embutida. - Alguns arquivos travam o jogo quando estão desempacotados, outros quando estão empacotados. O formato em si é estável; o carregador do motor se comporta de forma diferente entre as camadas do sistema de arquivos virtual e o acesso direto ao diretório. Ao criar mods, teste os dois estados.
Veja também
- TAF / TSF: a animação truecolor e sua forma em texto
.tsf, que os cabeçalhos.guireferenciam para os fundos dos menus. - GAF: animações
.tafcom paleta são referenciadas em todo arquivo.gui. - PCX: a convenção de PCX portador de paleta que o TA:K usa para os
.tafcom paleta. - As notas sobre os desafios dos formatos do TA:K nos materiais de referência deste repositório: armadilhas práticas ao portar recursos do TA para o TA:K.
- Glossário.