Merge pull request #79 from Lorenzooone/window-text-buffering
Teleport window text buffer + Player naming window text buffer
This commit is contained in:
commit
4a81263a81
125
src/c/vwf.c
125
src/c/vwf.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue