Merge pull request #79 from Lorenzooone/window-text-buffering

Teleport window text buffer + Player naming window text buffer
This commit is contained in:
jeffman 2019-09-22 14:01:42 -04:00 committed by GitHub
commit 4a81263a81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 275 additions and 8 deletions

View File

@ -28,6 +28,10 @@ int get_tile_number_buffer(int x, int y)
{
x--;
y--;
//Covers the alphabet-printing issues
if(y >= 0x10)
y -= 0xC;
int totalLenght = x + ((y >> 1) * 28);
int addedValue = (totalLenght >> 5) << 6;
return (totalLenght & 0x1F) + addedValue + (y & 1) * 32;
@ -494,6 +498,37 @@ void clear_window_header(int *dest, int length, int x, int y)
clear_rect_ram(dest, length, WINDOW_HEADER_BG);
}
//Prints the number header string in a tiny buffer and stores it in one go
int print_window_number_header_string(int *dest, byte *str, int x, int y)
{
int pixelX = x & 7;
int *destOffset = dest + ((x & ~7) + (y * 32));
int buffer[8 * 3];
for(int i = 0; i < 8 * 3; i++)
buffer[i] = 0x33333333;
for (;;)
{
byte code = *(str + 1);
if (code == 0xFF)
{
if (*str == 0)
break;
str += 2;
continue;
}
pixelX += print_character_to_ram(decode_character(*str++), buffer, pixelX, 4, 0xF);
}
for(int i = 0; i < 8 * 3; i++)
destOffset[i] = buffer[i];
return pixelX - (x & 7);
}
unsigned short* print_equip_header(int type, unsigned short *tilemap, unsigned int *dest, WINDOW *window)
{
byte *str = 0;
@ -965,8 +1000,8 @@ int player_name_printing_registration(byte* str, WINDOW* window)
}
String[24] = 0;
String[25] = 0xFF;
print_blankstr_window(0, 2, 24, window);
m2_printstr(window, String, 0, 1, 0);
print_blankstr_window_buffer(0, 2, 24, window);
printstr_buffer(window, String, 0, 1, 0);
return total;
}
@ -993,6 +1028,26 @@ void handle_first_window(WINDOW* window)
}
}
//Returns in *String a string containing "Talk to" and "Goods"
void setupShortMainMenu_Talk_to_Goods(char *String)
{
char Talk_to[] = "Talk to";
char Goods[] = "Goods";
int index = 0;
String[index++] = 0x5F;
String[index++] = 0xFF;
String[index++] = 0x08;
for(int i = 0; i < (sizeof(Talk_to) - 1); i++)
String[index++] = encode_ascii(Talk_to[i]);
String[index++] = 0x5F;
String[index++] = 0xFF;
String[index++] = 0x30;
for(int i = 0; i < (sizeof(Goods) - 1); i++)
String[index++] = encode_ascii(Goods[i]);
String[index++] = 0;
String[index++] = 0xFF;
}
int get_pointer_jump_back(byte *character)
{
byte *address1 = ((byte*)0x3004F24);
@ -1279,7 +1334,7 @@ byte print_character_with_codes(WINDOW* window, byte* dest)
{
handle_first_window_buffer(window, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
window->delay = window->delay_between_prints;
if(x > 0x1F)
if(window->text_x >= window->window_width || (window->text_x + window->window_x) > 0x1F)
{
window->text_y += 2;
window->text_x = 0;
@ -1693,6 +1748,64 @@ void print_blankstr_buffer(int x, int y, int width, byte *dest)
clear_rect_buffer(x, y, width, 2, dest);
}
//Function called for printing the alphabet. Seems to be a trimmed down version of the normal script-reading function. Probably done in order to make this faster
int print_alphabet_buffer(WINDOW* window)
{
byte* dest = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER));
if(window->redraw)
buffer_drawwindow(window, dest);
if(window->loaded_code == 0 || (*script_readability) != 0)
return 0;
window->delay = 0;
byte* str = window->text_start + window->text_offset;
while(true)
{
unsigned short y = window->window_y + window->text_y;
while(window->text_y >= window->window_height || y > 0x1F)
{
properScroll(window, dest);
y = window->window_y + window->text_y;
}
if(str[1] == 0xFF)
{
byte returnedVal = customcodes_parse_generic(str[0], str, window, dest);
if(returnedVal != 0)
{
window->text_offset += returnedVal;
str += returnedVal;
}
else if(str[0] == 1)
{
window->text_y += 2;
window->text_x = 0;
window->pixel_x = 0;
str += 2;
window->text_offset += 2;
}
else if(str[0] == 0)
{
window->loaded_code = 0;
return 0;
}
}
else
{
if(window->text_x >= window->window_width || (window->text_x + window->window_x) > 0x1F)
{
window->text_y += 2;
window->text_x = 0;
window->pixel_x = 0;
}
weld_entry_custom_buffer(window, str, 0, 0xF, dest);
str++;
window->text_offset++;
}
}
}
void load_pixels_overworld_buffer()
{
byte* buffer = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER));
@ -1770,6 +1883,12 @@ void store_pixels_overworld_buffer(int totalYs)
}
}
// x, y, width: tile coordinates
void print_blankstr_window_buffer(int x, int y, int width, WINDOW* window)
{
print_blankstr_buffer(x + window->window_x, y + window->window_y, width, (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)));
}
// x,y: tile coordinates
void copy_tile_buffer(int xSource, int ySource, int xDest, int yDest, byte *dest)
{

View File

@ -51,6 +51,7 @@ byte print_character_with_callback_1bpp_buffer(byte chr, int x, int y, byte *des
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground);
int print_window_header_string(int *dest, byte *str, int x, int y);
void clear_window_header(int *dest, int length, int x, int y);
int print_window_number_header_string(int *dest, byte *str, int x, int y);
unsigned short* print_equip_header(int type, unsigned short *tilemap, unsigned int *dest,
WINDOW *window);
unsigned short format_tile(unsigned short tile, bool flip_x, bool flip_y);
@ -82,6 +83,7 @@ void copy_name(byte *str, byte *source, int *index, int pos);
byte getSex(byte character);
void getPossessive(byte character, byte *str, int *index);
void getPronoun(byte character, byte *str, int *index);
void setupShortMainMenu_Talk_to_Goods(char *String);
int get_pointer_jump_back(byte *character);
void print_letter_in_buffer(WINDOW* window, byte* character, byte *dest);
void weld_entry_custom_buffer(WINDOW *window, byte *str, int font, int foreground, byte* dest);
@ -103,6 +105,8 @@ void setStuffWindow_Graphics();
void clearWindowTiles_buffer(WINDOW* window);
int initWindow_buffer(WINDOW* window, byte* text_start, unsigned short delay_between_prints);
void print_blankstr_buffer(int x, int y, int width, byte *dest);
void print_blankstr_window_buffer(int x, int y, int width, WINDOW* window);
int print_alphabet_buffer(WINDOW* window);
unsigned short ailmentTileSetup(byte *ailmentBase, unsigned short defaultVal);
int setNumber_getLength(int value, byte *str, int maxLength);
int print_string_in_buffer(byte *str, int x, int y, byte *dest);

View File

@ -1,5 +1,5 @@
//==============================================================================
// void parse_generic(int code, char* parserAddress, WINDOW* window, byte* dest)
// int parse_generic(int code, char* parserAddress, WINDOW* window, byte* dest)
// In:
// r0: code
// r1: parser address

View File

@ -153,6 +153,25 @@ mov r3,6
.org 0x80B9122 :: bl initWindow_buffer
.org 0x80B9142 :: bl baec6_psi_window_print_buffer
//---------------------------------------------------------
// Teleport window hacks
//---------------------------------------------------------
.org 0x80B9030 :: bl initWindow_buffer//Opening teleport window - "Where?"
.org 0x80B9036 :: bl print_window_with_buffer
.org 0x80B9040 :: bl b9040_special_string
.org 0x80B90D4 :: bl initWindow_buffer //Going back from teleport to the PSI window
.org 0x80B90DE :: bl initWindow_buffer
.org 0x80C5D1C :: bl initWindow_buffer //Initializes the actual teleport window
.org 0x80C5EB0 :: bl printstr_hlight_buffer
.org 0x80C5F46 :: bl printstr_hlight_buffer
.org 0x80C5F80 :: bl c5f80_printstr_hlight_buffer_store_buffer // Multiple pages initial case
.org 0x80C5EB0 :: bl printstr_hlight_buffer
.org 0x80C6134 :: bl clearWindowTiles_buffer
.org 0x80C61C8 :: lsl r0,r5,#3 :: add r0,r0,r5 :: nop //Proper string address
.org 0x80C6224 :: bl printstr_hlight_buffer
.org 0x80C625E :: bl c5f80_printstr_hlight_buffer_store_buffer // Multiple pages changing pages
.org 0x80C5F04 :: bl c5f04_store_if_done //Only one page case
//---------------------------------------------------------
// Class PSI window hacks
//---------------------------------------------------------
@ -1152,7 +1171,7 @@ nop
//---------------------------------------------------------
.org 0x80C5DE0 :: bl c65da_clean_print //To:
.org 0x80C5E30 :: bl c6190_clean_print //Number on first entering the menu
.org 0x80C6190 :: bl c6190_clean_print //Number on page change
.org 0x80C6190 :: bl c6190_buffer_number //Number on page change
.org 0x80C5E04 :: nop :: strh r0,[r4,#0] :: add r4,#2 :: nop ::nop //Remove extra tile
//---------------------------------------------------------
@ -1472,6 +1491,7 @@ nop
//Text Speed options
.org 0x8003BBC :: bl _4092_print_window_store //Printing + storing pixels
.org 0x8003C44 :: mov r3,#4 //Make highlighting the same speed for all text speeds
.org 0x8003FA2 :: bl _4092_print_window
.org 0x8003F8C :: mov r3,#4 //Print highlight of 4 tiles maximum
.org 0x8003E86 :: bl _3e86_special_setup //Avoid printing when not necessary
@ -1547,10 +1567,20 @@ nop
//==============================================================================
// Overworld player name alphabet
//==============================================================================
//"Register your name" in buffer
.org 0x80C6C54 :: bl printstr_buffer
//BLANK name in buffer
.org 0x80C6C7A :: bl printstr_buffer
//First time entering the menu's alphabet
.org 0x80C6D72 :: bl initWindow_buffer :: ldr r0,[r5,#0x10] :: bl c6d78_print_slphabet_store
//Player name printing - character is added
.org 0x80C75B4 :: bl c75b4_overworld_naming_top_printing :: b 0x80C777A
//Player name printing - character is deleted via add
//Player name printing - character is deleted via b button
.org 0x80C780E :: bl c780e_overworld_naming_top_printing :: b 0x80C789A
//Player name printing - character is deleted via backspace
@ -1746,6 +1776,7 @@ m2_coord_table_file:
.definelabel m2_psiwindow ,0x80C1FBC
.definelabel m2_drawwindow ,0x80C87D0
.definelabel m2_print_window ,0x80C8BE4
.definelabel m2_print_alphabet ,0x80C8FFC
.definelabel m2_printstr ,0x80C9634
.definelabel m2_printstr_hlight ,0x80C96F0
.definelabel m2_printnextch ,0x80C980C

View File

@ -1514,6 +1514,17 @@ pop {r0-r3}
bl 0x80CAB90
pop {pc}
//==============================================================================
//Routine which prints just the number with a tiny buffer
c6190_buffer_number:
push {lr}
lsl r2,r2,#3
lsl r3,r3,#3
bl print_window_number_header_string
add r0,#7
lsr r0,r0,#3
pop {pc}
//==============================================================================
//Routine which clears the header and THEN makes it so the string is printed
c65da_clean_print:
@ -1802,6 +1813,63 @@ pop {pc}
.pool
//==============================================================================
//Setup which only prints either "Talk to" and "Goods" in the main window.
b9040_special_string:
push {lr}
push {r0-r5}
add sp,#-76
ldr r5,=#0x3005078 //Make sure the game expects only the right amount of lines to be written (so only 1)
ldrb r4,[r5,#0]
str r4,[sp,#4]
mov r4,#0
strb r4,[r5,#0]
ldr r4,=#0x3005230 //Window generic address
//Main window
lsl r1,r0,#0x18
lsr r1,r1,#0x18
cmp r1,#0
bne @@end //Print only if there is an effective need to do so (So the routine before returned 0)
ldr r0,[r4,#0] //Main window place in ram
ldr r2,[r0,#4] //Save proper text_start and text_start2
str r2,[sp,#8]
ldr r2,[r0,#8]
str r2,[sp,#0xC]
ldrb r0,[r0,#0]
mov r2,#1
and r2,r0
cmp r2,#0
beq @@end //Check if window is enabled before printing in it
add r0,sp,#16
bl setupShortMainMenu_Talk_to_Goods //Get shortened menu string
mov r1,#0
str r1,[sp,#0]
add r1,sp,#16
ldr r0,[r4,#0]
mov r2,#5
mov r3,#2
bl 0x80BE4C8 //Let it do its things
ldr r0,[r4,#0]
bl print_window_with_buffer //Print text in the window
ldr r0,[r4,#0] //Restore text_start and text_start2
ldr r1,[sp,#8]
str r1,[r0,#4]
ldr r1,[sp,#0xC]
str r1,[r0,#8]
@@end:
ldr r4,[sp,#4]
strb r4,[r5,#0] //Restore expected amount of lines to be written
add sp,#76
pop {r0-r5}
lsl r0,r0,#0x18 //Clobbered code
lsr r0,r0,#0x18
pop {pc}
.pool
//==============================================================================
//Makes it sure the outer PSI window of the PSI Overworld menu prints the PSIs only once
b8cd2_psi_window:
@ -2067,6 +2135,18 @@ bl print_window_with_buffer
bl store_pixels_overworld
pop {pc}
//==============================================================================
//Calls printstr_hlight_buffer and then stores the buffer
c5f80_printstr_hlight_buffer_store_buffer:
push {r4,lr}
ldr r4,[sp,#8]
add sp,#-4
str r4,[sp,#0]
bl printstr_hlight_buffer
bl store_pixels_overworld
add sp,#4
pop {r4,pc}
//==============================================================================
//Fixes issue with sounds when going from the PSI window to the inner PSI window
b8d40_psi_going_inner_window:
@ -2830,6 +2910,7 @@ ldr r0,=#m2_player1
mov r1,r2
str r3,[sp,#0x24]
bl player_name_printing_registration
bl store_pixels_overworld_player_naming
pop {pc}
//==============================================================================
@ -2840,6 +2921,7 @@ ldr r1,=#0x3005230
ldr r1,[r1,#0x0C]
ldr r0,=#m2_player1
bl player_name_printing_registration
bl store_pixels_overworld_player_naming
pop {pc}
//==============================================================================
@ -2850,6 +2932,7 @@ ldr r1,=#0x3005230
ldr r1,[r1,#0x0C]
ldr r0,=#m2_player1
bl player_name_printing_registration
bl store_pixels_overworld_player_naming
pop {pc}
//==============================================================================
@ -2896,13 +2979,22 @@ bl m2_strlookup
mov r1,r0
mov r0,r4
mov r2,#0
bl m2_initwindow
bl initWindow_buffer
ldr r0,[r5,#0x10]
bl 0x80C8FFC //Print alphabet
bl print_alphabet_buffer //Print alphabet in buffer
bl store_pixels_overworld
@@end:
pop {pc}
//==============================================================================
//Prints the first alphabet and stores the buffer
c6d78_print_slphabet_store:
push {lr}
bl print_alphabet_buffer
bl store_pixels_overworld
pop {pc}
//==============================================================================
//Loads stuff up for the small alphabet and calls print_alphabet_if_needed
c73c0_small_overworld_alphabet:
@ -2966,6 +3058,18 @@ bl statusNumbersPrint
bl store_pixels_overworld
pop {pc}
//==============================================================================
//Routine which checks if all the teleport locations have been printed. If they do, it stores the buffer
c5f04_store_if_done:
push {lr}
lsr r5,r0,#0x10
ldr r2,[sp,#0x18]
cmp r0,r2
blt @@end
bl store_pixels_overworld
@@end:
pop {pc}
//==============================================================================
//Loads the vram into the buffer, it's called each time there is only the main file_select window active (a good way to set the whole thing up)
load_pixels_overworld:
@ -2982,6 +3086,15 @@ mov r0,#0x10
bl store_pixels_overworld_buffer
pop {r0-r3,pc}
//==============================================================================
//Stores the buffer into the vram. This avoids screen tearing.
store_pixels_overworld_player_naming:
push {r0-r3,lr}
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
mov r0,#0x4
bl store_pixels_overworld_buffer
pop {r0-r3,pc}
//==============================================================================
//Stores the buffer into the vram. This avoids screen tearing.
store_pixels_overworld_psi_window: