Registrarse

[pokeruby - pokeemerald] Modificaciones a las textboxes

Dragonite

But where's your heart
Miembro del equipo
Moderador/a
Encargado/a de Eventos
Nota importante: Ya que pokeruby está tan lleno de bugs y actualmente mucha gente del decomp directamente se pasó a pokeemerald, he decidido concentrarme sólo en pokeemerald y no agregar nuevas funciones para pokeruby. Si te das maña, con ver las implementaciones de pokeemerald, tendría que ser relativamente sencillo pasarlo a pokeruby.

[hr][/hr]

Cambiar la textbox original por los frames del menú de opciones

Con este tutorial podemos cambiar la textbox a uno de los frames que habitualmente se usan para lo que no son diálogos (menús, diálogo de birch, comandos YES/NO, etc.)

Es bastante sencillo hacer esto, y no necesitamos ninguna herramienta especial.

Lo primero que nada, es cambiar algunos parámetros para que el pokeruby/pokeemerald ignore la textbox que estaba usando hasta ahora (la clásica azul celeste de toda la vida, vamos).

Esto se hace modificando algunas piezas de código:​

Reemplazando la línea 240 del archivo src/text_window.c por esto.
Código:
/* static */void DrawDialogueFrame(struct Window *win, u8 left, u8 top, u8 width, u8 height)
Reemplazando la línea 19 con esto.
Código:
/*static*/ void DrawDialogueFrame(struct Window *win, u8 left, u8 top, u8 width, u8 height);
Reemplazando desde la línea 253 hasta la 266 con esto.​
Código:
// Draws an alternate styled frame used for dialogue windows that appear on the overworld
void TextWindow_DrawDialogueFrame(struct Window *win)
{
    //DrawDialogueFrame(win, STD_DLG_FRAME_LEFT, STD_DLG_FRAME_TOP, STD_DLG_FRAME_WIDTH, STD_DLG_FRAME_HEIGHT);
    TextWindow_DrawStdFrame(win, STD_DLG_FRAME_LEFT, STD_DLG_FRAME_TOP, STD_DLG_FRAME_LEFT + STD_DLG_FRAME_WIDTH, STD_DLG_FRAME_TOP + STD_DLG_FRAME_HEIGHT);    
}

// Loads the dialogue window frame tiles into VRAM
void TextWindow_LoadDialogueFrameTiles(struct Window *win)
{
   // u8 *tileData = win->template->tileData;
   // CpuFastCopy(gDialogueFrame_Gfx, tileData + 32 * sDialogueFrameBaseTileNum, 14 * TILE_SIZE_4BPP);
   TextWindow_LoadStdFrameGraphics(win);
}
Reemplazando desde la linea 10 a la 13 con esto.​
Código:
#define STD_DLG_FRAME_LEFT    0
#define STD_DLG_FRAME_TOP    14
#define STD_DLG_FRAME_WIDTH  29
#define STD_DLG_FRAME_HEIGHT  5
Debemos buscar el archivo src/menu.c e ir a la siguiente línea: (No pongo el número exacto porque puede diferir entre versiones)

Código:
void WindowFunc_DrawDialogueFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 paletteNum)
Y reemplazamos toda la función con esta:

Función nueva

Tener cuidado al reemplazar de no pasarse o quedarse corto, siempre reemplazar hasta el último } que es siempre el que más a la izquierda está.

NOTA MUY IMPORTANTE: En Pokeemerald hay un pequeño cambio con respecto a cómo funciona el texto. El primer color es utilizado para la transparencia de la textbox, pero el segundo es usado para el fondo del texto, el tercero es para el color principal del texto y el cuarto es para el color secundario (el que actúa de sombra, vamos). Por lo tanto, si no tienes planes de modificarlos, deberás tener un color blanco en el segundo, un negro en el tercero y un grisado en el cuarto.
Guardamos y compilamos. Si todo salió bien, se debería ver más o menos así:



La ventaja que tiene este método es que las imágenes que utiliza para insertar los frames son muy sencillas de editar, son un cuadrado y ya, vamos copiando cualquier textbox y vamos reemplazando sobre el frame original. En cambio, el dialogbox por defecto tiene un tilemap bastante extraño, por lo cual es bastante engorroso modificarlo.

Ahora, puedes reemplazar cualquier frame de la carpeta graphics/text_window y luego elegir ese frame para que se vea en el juego. Si modificas el 1.png, estarás modificando el frame 1, si modificas el 2.png, estarás modificando el frame 2 y así.

Yo por ejemplo, voy a insertar la primera textbox de esta plantilla:https://www.spriters-resource.com/ds_dsi/pokemonheartgoldsoulsilver/sheet/26753/

Debemos respetar esta estructura para que la imagen se vea bien luego:


Las esquinas deben medir 8x8, los bordes 8x8 y el centro debe quedar como está (salvo que queramos ponerle un fondo al textbox, pero eso implica hacer unas modificaciones a la rutina de textos) (esto último sólo es válido en pokeruby)

Cuando ya esté listo, el procedimiento para insertar imágenes es el mismo de siempre (indexar todo, exportar la paleta, borrar el .4bpp y el .gbapal y compilar)

Y este es el resultado final:


(Sí, ya sé que el textbox es distinto, es que simplemente copié y pegué la misma esquina y borde para los 4 lados. Lo importante es que se insertó bien.)

[hr][/hr]
Cambiar los textboxes en tiempo de ejecución

Ahora que tenemos 20 textboxes elegibles, podemos hacer cosas muy variadas con eso! No hace falta que nos limitemos a insertar solo una textbox o darle varias opciones al usuario (que realmente pocos cambian o directamente ignoran). Con esta sencilla modificación, podremos desde el script, llamar un comando y elegir la que queramos!

(supondré que todos usan pokeemerald. Si usas pokeruby, deberás buscar los archivos manualmente en caso de que no estén en las mismas rutas)

Primero, debemos crear las llamadas al comando. Primero iremos a "data/script_cmd_table.inc" y agregamos esto:

Código:
[LEFT]	.4byte changeframe              [/LEFT]
Luego, vamos a "asm/macros/event.inc" y agregamos lo siguiente:

Código:
[LEFT]	.macro changeframe frameNumber:req
	.byte 0xe3
	.2byte \frameNumber
	.endm[/LEFT]
ATENCIÓN: donde dice ".byte 0xe3" eso será válido sólo en caso de que la rutina anterior (es decir, la de arriba en el archivo) tenga el 0xe2 asignado. Si no, tendrán que poner el valor adecuado (siempre el siguiente al que se usó antes, teniendo en cuenta que el valor está en hexadecimal)

Luego, iremos a "src/scrcmd.c" e insertaremos la función:

Código:
[LEFT]void ScrCmd_changeframe(struct ScriptContext *ctx)
{
	u8 frameNumber = ScriptReadByte(ctx);
	
	frameNumber--;
	gSaveBlock2Ptr->optionsWindowFrameType = frameNumber;	
}[/LEFT]
Código:
[LEFT]void ScrCmd_changeframe(struct ScriptContext *ctx)[/LEFT]
Con esto le estamos indicando al compilador que vamos a usar los parámetros que están seteados en el archivo de macros.

Código:
[LEFT]u8 frameNumber = ScriptReadByte(ctx);[/LEFT]
Esto inicializa el parámetro que utilizaremos en una unsigned8, que significa que no tendrá un formato específico (puede contener cualquier cosa) y que el contenido irá en grupos de 1 bit (es decir, sin agrupar)

Código:
[LEFT]frameNumber--;[/LEFT]
Esto le resta uno al valor que utilicemos como parámetro. Cuando creé la rutina por primera vez, me sucedía que si intentaba cargar la 2, me cargaba la 3 y si intentaba cargar la 1, me cargaba la 2. Entendí que por alguna extraña razón, comienza de 0 cuando los archivos de frame comienzan desde 1. Esto soluciona ese error.

Código:
[LEFT]gSaveBlock2Ptr->optionsWindowFrameType = frameNumber;[/LEFT]
Esto guarda el valor que seteamos en la RAM y en el save block, de la misma forma que lo haría si lo hiciéramos desde el menú de opciones (por eso funciona incluso cuando guardamos y reiniciamos el emulador)

Una vez que hagamos todo esto, luego sólo tenemos que usar el comando y el parámetro será el textbox que queremos usar (nos vale tanto el número de archivo como el número de frame que salga en las opciones)

Código:
[LEFT]changeframe 2[/LEFT]
Y os quedará algo así.



(para hacer lo del GIF, antes del msgbox cambié al frame 2 e inmediatamente después vuelvo al 1 que es el default)

[hr][/hr]

Ojalá les ayuden estas implementaciones, pueden hacer cosas muy interesantes con ellas, y planeo seguir ahondando en esto.

¡Hasta la próxima!
 
Última edición:

InmortalKaktus

Ludiloco
Respuesta: [Poke*] Cambiar la textbox

Yay!

Esto es muy útil, además, de que si sabes arreglártelas bien con C, puedes inclusive crear textbox personalizadas, y no tendrían porqué tener tan sólo el marco exterior, y el interior para el texto, sino que se podría jugar con detalles.

Un gran aporte, a ver si te animas, y consigues hacer que se pueda elegir cuál usar de forma dinámica en el propio juego.

¡Sigue así!
 

Dragonite

But where's your heart
Miembro del equipo
Moderador/a
Encargado/a de Eventos
Respuesta: [Poke*] Cambiar la textbox

Yay!

Esto es muy útil, además, de que si sabes arreglártelas bien con C, puedes inclusive crear textbox personalizadas, y no tendrían porqué tener tan sólo el marco exterior, y el interior para el texto, sino que se podría jugar con detalles.

Un gran aporte, a ver si te animas, y consigues hacer que se pueda elegir cuál usar de forma dinámica en el propio juego.

¡Sigue así!
Seguí tu sugerencia y agregué eso al tutorial. Planeo hacer de este un tutorial especialmente dedicado a las textboxes. Si aprecias bien el GIF de abajo, quizá te des cuenta el próximo tutorial que quiero hacer ;)
 
Arriba