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

Equip window text buffering + Sounds
This commit is contained in:
jeffman 2019-09-16 20:56:54 -04:00 committed by GitHub
commit f968305573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 871 additions and 77 deletions

View File

@ -18,6 +18,7 @@ $input_c_files =
"src/c/fileselect.c",
"src/c/status.c",
"src/c/battle.c",
"src/c/equip.c",
"src/c/psi.c"
$base_c_address = 0x83755B8;

View File

@ -9,10 +9,10 @@ void printTargetOfAttack(short a, short target)
WINDOW *window = getWindow(3);
m2_setupwindow(window, 0x9, 0x3, 0x14, 0x2);
initWindow_buffer(window, NULL, 0);
printstr_buffer(window, &m12_battle_commands_str11, 0, 0, false); //To
printstr_buffer(window, m12_battle_commands_str11, 0, 0, false); //To
if(target != -1)
{
printstr_hlight_buffer(window, &m12_battle_commands_str14, 8, 0, false);// " "
printstr_hlight_buffer(window, m12_battle_commands_str14, 8, 0, false);// " "
short *pointer = (short*)(0x20248E0 + 0x83E);
byte *pointer2 = (byte*)(pointer);
short value = *pointer;
@ -39,9 +39,9 @@ void printTargetOfAttack(short a, short target)
else
{
if(a == 0) //a is the row here
printstr_buffer(window, &m12_battle_commands_str12, 2, 0, false); //the Front Row
printstr_buffer(window, m12_battle_commands_str12, 2, 0, false); //the Front Row
else
printstr_buffer(window, &m12_battle_commands_str13, 2, 0, false); //the Back Row
printstr_buffer(window, m12_battle_commands_str13, 2, 0, false); //the Back Row
}
}
@ -59,12 +59,12 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
if((*drawValue) == 2)
{
print_blankstr_buffer(7,1,5,(int*)(OVERWORLD_BUFFER - 0x2000));
str = &m12_battle_commands_str10; //Do Nothing
str = m12_battle_commands_str10; //Do Nothing
}
else if((*drawValue) == 1)
str = &m12_battle_commands_str6; //Shoot
str = m12_battle_commands_str6; //Shoot
else
str = &m12_battle_commands_str0; //Bash
str = m12_battle_commands_str0; //Bash
printstr_hlight_buffer(window, str, 1, 0, highlighted & 1);
}
@ -72,9 +72,9 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
{
print_blankstr_buffer(2,3,5,(int*)(OVERWORLD_BUFFER - 0x2000));
if((*active_window_party_member) != 2)
printstr_hlight_buffer(window, &m12_battle_commands_str3, 1, 1, highlighted & 2); //PSI
printstr_hlight_buffer(window, m12_battle_commands_str3, 1, 1, highlighted & 2); //PSI
else
printstr_hlight_buffer(window, &m12_battle_commands_str7, 1, 1, highlighted & 2); //Spy
printstr_hlight_buffer(window, m12_battle_commands_str7, 1, 1, highlighted & 2); //Spy
}
}
@ -85,7 +85,7 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
if((*drawValue) != 2)
{
print_blankstr_buffer(7,1,5,(int*)(OVERWORLD_BUFFER - 0x2000));
printstr_hlight_buffer(window, &m12_battle_commands_str1, 6, 0, highlighted & 4); //Goods
printstr_hlight_buffer(window, m12_battle_commands_str1, 6, 0, highlighted & 4); //Goods
}
}
@ -94,7 +94,7 @@ void printBattleMenu(byte validXs, byte validYs, byte highlighted)
print_blankstr_buffer(7,3,5,(int*)(OVERWORLD_BUFFER - 0x2000));
if((*drawValue) != 2)
{
printstr_hlight_buffer(window, &m12_battle_commands_str4, 6, 1, highlighted & 8); //Defend
printstr_hlight_buffer(window, m12_battle_commands_str4, 6, 1, highlighted & 8); //Defend
}
}
}

View File

@ -6,16 +6,16 @@
void printTargetOfAttack(short a, short target);
void printBattleMenu(byte validXs, byte validYs, byte highlighted);
extern byte m12_battle_commands_str0;
extern byte m12_battle_commands_str1;
extern byte m12_battle_commands_str3;
extern byte m12_battle_commands_str4;
extern byte m12_battle_commands_str6;
extern byte m12_battle_commands_str7;
extern byte m12_battle_commands_str10;
extern byte m12_battle_commands_str11;
extern byte m12_battle_commands_str12;
extern byte m12_battle_commands_str13;
extern byte m12_battle_commands_str14;
extern byte m12_battle_commands_str0[];
extern byte m12_battle_commands_str1[];
extern byte m12_battle_commands_str3[];
extern byte m12_battle_commands_str4[];
extern byte m12_battle_commands_str6[];
extern byte m12_battle_commands_str7[];
extern byte m12_battle_commands_str10[];
extern byte m12_battle_commands_str11[];
extern byte m12_battle_commands_str12[];
extern byte m12_battle_commands_str13[];
extern byte m12_battle_commands_str14[];
#endif

547
src/c/equip.c Normal file
View File

@ -0,0 +1,547 @@
#include "window.h"
#include "equip.h"
#include "number-selector.h"
#include "locs.h"
int equipReadInput(WINDOW* window) //Returns the character whose window we're going in, ACTION_NONE if nothing happens or ACTION_STEPOUT if going out of this window
{
unsigned short previousCharacter = *active_window_party_member;
int currentCharacter = previousCharacter;
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
bool printed = false; //Used to avoid sound issues. If we printed, we don't make sounds
if(state.right && !window->hold)
currentCharacter += 1;
if(state.left && !window->hold)
currentCharacter -= 1;
if((state.left || state.right) && !window->hold)
{
window->unknown7 = 0;
if(state.left)
{
if(currentCharacter < 0)
currentCharacter = 3;
int foundChar = currentCharacter;
for(int i = 0; i < 4; i++)
{
if (foundChar < 0)
foundChar = 3;
if ((*pc_flags)[foundChar])
break;
foundChar--;
}
currentCharacter = foundChar;
}
else
{
if(currentCharacter > 3)
currentCharacter = 0;
int foundChar = currentCharacter;
for(int i = 0; i < 4; i++)
{
if (foundChar > 3)
foundChar = 0;
if ((*pc_flags)[foundChar])
break;
foundChar++;
}
currentCharacter = foundChar;
}
(*active_window_party_member) = currentCharacter;
if(currentCharacter != previousCharacter) //Print only if needed
{
equipPrint(window);
printed = true;
}
}
if(state_shadow.right || state_shadow.left)
{
if(state.right || state.left)
{
if(currentCharacter != previousCharacter)
m2_soundeffect(0x131);
}
window->hold = true;
}
else
window->hold = false;
if(state.b || state.select)
{
if(!printed)
m2_soundeffect(0x12E);
window->counter = 0;
return ACTION_STEPOUT;
}
else if(state.a || state.l)
{
if(!printed)
m2_soundeffect(0x12D);
if((*pc_count) > 1)
{
unsigned short *arrangementBase = (*tilemap_pointer) + (((window->window_y - 1) << 5) + window->window_x + window->window_width - 4);
unsigned short topTile = ((*tile_offset) + 0x96) | (*palette_mask) | 0x800;
(*arrangementBase) = topTile;
(*(arrangementBase + 1)) = topTile;
(*(arrangementBase + 2)) = topTile;
(*(arrangementBase + 3)) = topTile;
}
window->counter = 0;
return 1;
}
window->counter++;
if (*pc_count > 1)
{
// We're doing a bit of simplification here.
// The Japanese version tries to highlight the arrow you pressed.
// It only shows for a couple frames and it looks weird, so we're
// just going to show the arrows and not bother with the direction indicator.
draw_window_arrows(window, window->counter < 8);
}
if (window->counter > 16)
window->counter = 0;
return ACTION_NONE;
}
void equippablePrint(WINDOW* window) //Prints equippable items (The innermost equip window)
{
unsigned short savedValue = 0;
byte* freeSpace = free_strings_pointers[3];
byte *none = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x2C);
PC *character_data = &(m2_ness_data[*active_window_party_member]);
unsigned short* something = (unsigned short*)0x3005224;
unsigned short* something2 = (unsigned short*)0x300522C;
for(int i = 0; i < 7; i++)
freeSpace[i] = 0;
freeSpace[7] = 0xFF;
int* headerAddress = (int*)(((int)vram) + ((*something2) << 0xE) + ((*tile_offset) << 5));
map_tile(0xB3, window->window_x, window->window_y - 1);
unsigned short val = *something;
if(!window->vwf_skip)
clear_window_header(headerAddress, 8, 0x10, 0x11);
unsigned short* lastUsed = print_equip_header(*something, (unsigned short*)((*tilemap_pointer) + (((window->window_y - 1) << 5) + window->window_x + 1)), headerAddress, window);
window->vwf_skip = true;
if(window->cursor_x > 6) //Mode which prints only 5 items in M12. Used if one has more than 8 items of an equippable kind.
{
clearWindowTiles_buffer(window);
short counter = 0;
while(counter < 5)
{
int value = (window->cursor_x_base * 5) + counter;
byte equippables;
if(value <= 0xD)
equippables = *(window->number_text_area + 4 + value);
else
equippables = 0xFF;
if(equippables == 0xFF)
{
freeSpace[counter] = 0xFD;
printstr_buffer(window, none, 1, counter, false);
break;
}
else
{
byte *item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[equippables - 1]);
byte x = 1;
if(m2_isequipped(equippables))
{
map_special_character(0x1DE,(window->window_x + 1), (counter << 1) + 1); //Print the E
x++;
}
printstr_buffer(window, item, x, counter, false);
freeSpace[counter] = equippables;
counter++;
}
}
byte* str = NULL;
switch(val)
{
case 3:
str = m12_other_str9; //->Weapons
break;
case 4:
str = m12_other_str10; //->Body
break;
case 5:
str = m12_other_str11; //->Arms
break;
case 6:
str = m12_other_str12; //->Other
break;
default:
break;
}
if(str != NULL)
savedValue = printstr_buffer(window, str, 1, 6, false); //Prints the string, savedValue is used to understand where to print "(X)"
int tmp = m2_div(window->cursor_x, 5);
str = NULL;
if(tmp <= window->cursor_x_base)
str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x8C);
else
str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x8D + window->cursor_x_base);
printstr_hlight_pixels_buffer(window, str, savedValue, 6 << 4, false); //Prints "(X)"
freeSpace[5] = 0;
freeSpace[6] = 0xFE;
freeSpace[7] = 0xFF;
}
else //Prints up to 7 equippable items. It's the same as the above cycle, without the cursor_x_base stuff.
{
short counter = 0;
while(counter < 7)
{
byte equippables = *(window->number_text_area + 4 + counter);
if(equippables == 0xFF)
{
freeSpace[counter] = 0xFD;
freeSpace[counter + 1] = 0xFF; //Different from the cycle above
printstr_buffer(window, none, 1, counter, false);
break;
}
else
{
byte *item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[equippables - 1]);
byte x = 1;
if(m2_isequipped(equippables))
{
map_special_character(0x1DE,(window->window_x + 1), (counter << 1) + 1); //Print the E
x++;
}
printstr_buffer(window, item, x, counter, false);
freeSpace[counter] = equippables;
counter++;
}
}
}
window->loaded_code = 0;
}
int equippableReadInput(WINDOW* window) //Manages input in equipment-choice innermost window. Returns the equippable item the cursor is on or ACTION_STEPOUT
{
byte* freeSpace = free_strings_pointers[3];
PC *character_data = &(m2_ness_data[*active_window_party_member]);
bool printed = (window->loaded_code == 1);
// Get weird sign height value
unsigned short height = window->window_height;
unsigned int height_sign_bit = height >> 15;
unsigned int weird_value = (((height + height_sign_bit) << 15) >> 16);
// Clear cursor tiles
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2);
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2 + 1);
if(window->loaded_code == 1) //We're printing
equippablePrint(window);
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
unsigned short possibleEquippablesCount = window->cursor_x;
short previousY = window->cursor_y;
short currentY = window->cursor_y;
int counter = 0;
//Loads the total amount of items
if(possibleEquippablesCount > 6)
counter = 7;
else if(weird_value > 0)
while(counter < weird_value && freeSpace[counter] != 0xFF)
counter++;
if(state.up)
{
currentY--;
if(currentY < 0)
{
if(window->hold)
currentY = 0;
else
currentY = counter - 1;
}
else
while(freeSpace[currentY] == 0)
currentY--;
}
if(state.down)
{
currentY++;
if(currentY >= counter)
{
if(window->hold)
currentY = counter - 1;
else
currentY = 0;
}
else
while(freeSpace[currentY] == 0)
currentY++;
}
if(state_shadow.up || state_shadow.down)
{
window->counter = 0;
if(previousY != currentY)
m2_soundeffect(0x12F);
window->hold = true;
window->cursor_y = currentY;
}
else
window->hold = false;
if(state.b || state.select)
{
window->counter = 0;
m2_soundeffect(0x12E);
return ACTION_STEPOUT;
}
if((state.a || state.l) && !printed) //Avoid sound issues when going into the window
{
window->counter = 0xFFFF;
if(freeSpace[window->cursor_y] == 0xFE)
{
m2_soundeffect(0x12D); //Do the sound only if we're changing the page. Otherwise the original code will do the appropriate sound
window->counter = 0;
window->cursor_x_base++;
if(m2_div(window->cursor_x, 5) < window->cursor_x_base)
window->cursor_x_base = 0;
return 0xFE; //Change window counter
}
if(window->cursor_y + 1 < counter)
return freeSpace[window->cursor_y]; //Equipment
return 0xFD; //None
}
if (window->counter != 0xFFFF)
{
window->counter++;
// Draw cursor for current item
map_special_character((window->counter <= 7) ? 0x99 : 0x9A,
window->window_x,
window->window_y + window->cursor_y * 2);
if (window->counter > 0x10)
window->counter = 0;
}
if(window->cursor_y + 1 < counter)
return freeSpace[window->cursor_y];
return 0xFD; //None
}
//Simplified inner equip routine (The original routine had a pointer to a table of valid cursor positions as a parameter)
int innerEquipInput(WINDOW* window)
{
bool printing = !window->vwf_skip;
window->vwf_skip = true;
PAD_STATE state = *pad_state;
PAD_STATE state_shadow = *pad_state_shadow;
short previousY = window->cursor_y;
short currentY = window->cursor_y;
// Clear cursor tiles
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2);
map_tile(0x1FF, window->window_x, window->window_y + window->cursor_y * 2 + 1);
if(state.up) //This has been simplified
{
currentY--;
if(currentY < 0)
{
if(window->hold)
currentY = 0;
else
currentY = 3;
}
}
if(state.down) //This has been simplified
{
currentY++;
if(currentY >= 4)
{
if(window->hold)
currentY = 3;
else
currentY = 0;
}
}
//The game does stuff when pressing left or right, however for the equipment window this is not needed
if(state.right) //This routine in particular did both the main overworld window and the inner equip window
{
}
if(state.left)
{
}
if(state_shadow.up || state_shadow.down)
{
window->counter = 0;
if(previousY != currentY)
m2_soundeffect(0x12F);
window->hold = true;
window->cursor_y = currentY;
}
else
window->hold = false;
if((state.b || state.select) && (!printing))
{
window->counter = 0;
m2_soundeffect(0x12E);
window->vwf_skip = false;
return ACTION_STEPOUT;
}
if((state.a || state.l) && (!printing))
{
window->counter = 0xFFFF;
m2_soundeffect(0x12D);
window->vwf_skip = false;
return (window->cursor_y << 1) + ACTION_STEPIN;
}
if (window->counter != 0xFFFF)
{
window->counter++;
// Draw cursor
map_special_character((window->counter <= 7) ? 0x99 : 0x9A,
window->window_x,
window->window_y + window->cursor_y * 2);
if (window->counter > 0x10)
window->counter = 0;
}
return ACTION_NONE;
}
void equipPrint(WINDOW* window) //Prints equipment
{
m2_hpwindow_up(*active_window_party_member);
// Draw window header
map_tile(0xB3, window->window_x, window->window_y - 1);
clear_name_header(window);
copy_name_header(window, *active_window_party_member);
PC *character_data = &(m2_ness_data[*active_window_party_member]);
byte *nothing = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x2A);
byte *item;
//Clear the previous equipment
print_blankstr_buffer(window->window_x + 6, 1, 0xC, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(window->window_x + 6, 3, 0xC, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(window->window_x + 6, 5, 0xC, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(window->window_x + 6, 7, 0xC, (int*)(OVERWORLD_BUFFER - 0x2000));
//Clear the previous numbers
print_blankstr_buffer(7, 0xB, 0x8, (int*)(OVERWORLD_BUFFER - 0x2000));
print_blankstr_buffer(7, 0xD, 0x8, (int*)(OVERWORLD_BUFFER - 0x2000));
//Reprint the ":"s
print_character_with_callback(decode_character(0x6A), ((window->window_x + 6) << 3), (0x1 << 3), 0, 0xF, (int*)(OVERWORLD_BUFFER - 0x2000), &get_tile_number_with_offset, *tilemap_pointer, 32, 0xC);
print_character_with_callback(decode_character(0x6A), ((window->window_x + 6) << 3), (0x3 << 3), 0, 0xF, (int*)(OVERWORLD_BUFFER - 0x2000), &get_tile_number_with_offset, *tilemap_pointer, 32, 0xC);
print_character_with_callback(decode_character(0x6A), ((window->window_x + 6) << 3), (0x5 << 3), 0, 0xF, (int*)(OVERWORLD_BUFFER - 0x2000), &get_tile_number_with_offset, *tilemap_pointer, 32, 0xC);
print_character_with_callback(decode_character(0x6A), ((window->window_x + 6) << 3), (0x7 << 3), 0, 0xF, (int*)(OVERWORLD_BUFFER - 0x2000), &get_tile_number_with_offset, *tilemap_pointer, 32, 0xC);
//Print the equipment
if(character_data->equipment[0] == 0) //Weapon
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x1) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[0] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x1); //Print the E
printstr_buffer(window, item, 8, 0, false);
}
if(character_data->equipment[1] == 0) //Body
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x3) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[1] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x3); //Print the E
printstr_buffer(window, item, 8, 1, false);
}
if(character_data->equipment[2] == 0) //Arms
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x5) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[2] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x5); //Print the E
printstr_buffer(window, item, 8, 2, false);
}
if(character_data->equipment[3] == 0) //Other
print_string_in_buffer(nothing, (((window->window_x + 7)) << 3) - 2, (0x7) << 3, (int*)(OVERWORLD_BUFFER - 0x2000));
else
{
item = m2_strlookup((int*)0x8B1AF94, (byte*)0x8B1A694, character_data->goods[character_data->equipment[3] - 1]);
map_special_character(0x1DE,(window->window_x + 7), 0x7); //Print the E
printstr_buffer(window, item, 8, 3, false);
}
}
//Prints the numbers in the window in a formatted way
void printNumberEquip(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight)
{
while((*str) == 0x50)
{
x += 6;
str++;
}
printstr_hlight_pixels_buffer(window, str, x, y, highlight);
}
//Prints Offense: and Defense:
void printEquipWindowNumberText(WINDOW* window)
{
handle_first_window_buffer(window, (int*)(OVERWORLD_BUFFER - ((*tile_offset) * 32)));
printstr_hlight_pixels_buffer(window, window->text_start, 0, 3, false);
}
//Prints the arrow for the numbers in the Offense/Defense menu
void printEquipNumbersArrow(WINDOW* window)
{
printTinyArrow((window->window_x + 9) << 3, (window->window_y + 0) << 3);
printTinyArrow((window->window_x + 9) << 3, (window->window_y + 2) << 3);
}

20
src/c/equip.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef HEADER_EQUIP_INCLUDED
#define HEADER_EQUIP_INCLUDED
#include "vwf.h"
void equipPrint(WINDOW* window);
int equipReadInput(WINDOW* window);
void equippablePrint(WINDOW* window);
int equippableReadInput(WINDOW* window);
int innerEquipInput(WINDOW* window);
void printEquipWindowNumberText(WINDOW* window);
void printEquipNumbersArrow(WINDOW* window);
extern byte m12_other_str9[];
extern byte m12_other_str10[];
extern byte m12_other_str11[];
extern byte m12_other_str12[];
#endif

View File

@ -28,7 +28,6 @@ void setup_User_Dead(byte *String, int *index, byte user, byte target, byte item
void setup_Both_Dead(byte *String, int *index, byte user, byte target, byte item);
void give_print(byte item, byte target, byte source, WINDOW *window, byte *str);
extern bool m2_isequipped(int item_index);
extern void m2_soundeffect(int index);
extern int m2_div(int dividend, int divisor);
extern int m2_sub_a334c(int value);

View File

@ -181,6 +181,20 @@ void print_special_character(int tile, int x, int y)
cpufastset(&vram[(sourceTileIndex + 32) * 8], &vram[(destTileIndex + 32) * 8], 8);
}
// Prints a special tile. Pixels are not copied.
// x, y in pixels
void print_special_character_buffer(int tile, int x, int y)
{
// Special graphics must be tile-aligned
x >>= 3;
y >>= 3;
unsigned short sourceTileIndex = tile + *tile_offset;
(*tilemap_pointer)[x + (y * 32)] = sourceTileIndex | *palette_mask;
(*tilemap_pointer)[x + ((y + 1) * 32)] = (sourceTileIndex + 32) | *palette_mask;
}
// Maps a special character to the given tile coordinates. Only the tilemap is changed.
// x, y in tiles
void map_special_character(unsigned short tile, int x, int y)
@ -398,9 +412,21 @@ unsigned short* print_equip_header(int type, unsigned short *tilemap, unsigned i
// Print (X)
if (window->cursor_x > 6)
{
int buffer[8 * 3];
int mask = WINDOW_HEADER_BG;
for(int i = 0; i < (width & 7); i++) //Saves only the important pixels and deletes the rest in the buffer
mask = (mask << 4) | 0xF;
int *destOffset = dest + (((startX + width) & ~7) + (startY * 32));
for(int i = 0; i < 8; i++)
buffer[i] = destOffset[i] & mask;
for(int i = 0; i < 8 * 2; i++)
buffer[8 + i] = WINDOW_HEADER_BG;
int base = window->cursor_x_base;
str = m2_strlookup(m2_misc_offsets, m2_misc_strings, base + 0x8C);
width += print_window_header_string(dest, str, startX + width, startY);
width += print_window_header_string(buffer, str, width & 7, 0);
for(int i = 0; i < 8 * 3; i++) //Restore the vram
destOffset[i] = buffer[i];
}
// Update tilemap
@ -1160,15 +1186,15 @@ byte print_character_formatted_buffer(byte chr, int x, int y, int font, int fore
// 0x64 to 0x6C (inclusive) is YOU WON
if ((chr >= YOUWON_START) && (chr <= YOUWON_END))
{
print_special_character(chr + 0xF0, x, y);
print_special_character_buffer(chr + 0xF0, x, y);
return 8;
}
// 0x6D is an arrow ->
else if (chr == ARROW)
if (chr == ARROW)
{
print_special_character(ARROW + 0x30, x, y);
return 8;
print_special_character_buffer(ARROW + 0x30, x, y);
return 9;
}
return print_character_with_callback(chr, x, y, font, foreground, dest, &get_tile_number_with_offset, *tilemap_pointer, 32, 0xC);
@ -1229,18 +1255,29 @@ int print_string_in_buffer(byte *str, int x, int y, int *dest)
int initial_x = x;
int charCount = 0;
while (str[1] != 0xFF)
while (str[1] != 0xFF || str[0] != 0)
{
if(str[1] == 0xFF && str[0] == 1)
{
x = initial_x;
str += 2;
y+= 0x10;
}
else if(str[1] != 0xFF)
{
x += print_character_formatted_buffer(decode_character(*str++), x, y, 0, 0xF, dest);
charCount++;
}
else
break;
}
int totalWidth = x - initial_x;
return (charCount & 0xFFFF) | (totalWidth << 16);
}
void printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight)
int printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight)
{
int tmpOffset = window->text_offset;
int tmpOffset2 = window->text_offset2;
@ -1266,7 +1303,7 @@ void printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short
window->delay = 0;
output = print_character_with_codes(window, (int*)(OVERWORLD_BUFFER - ((*tile_offset) * 32)));
}
int retValue = (window->text_x << 3) + window->pixel_x;
window->text_start = tmpTextStart;
window->text_offset = tmpOffset;
window->text_offset2 = tmpOffset2;
@ -1274,6 +1311,7 @@ void printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short
window->text_y = tmpText_y;
window->delay_between_prints = tmpDelayPrints;
(*palette_mask) = tmpPaletteMsk;
return retValue;
}
unsigned short printstr_hlight_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight)
@ -1515,6 +1553,11 @@ unsigned short ailmentTileSetup(byte *ailmentBase, unsigned short defaultVal)
return (*(returnValues + (value * 7) + flagValue - 1));
}
void printTinyArrow(int x, int y)
{
print_special_character_buffer(0x9F, x, y);
}
void printCashWindow()
{
(*window_flags) |= 2;

View File

@ -29,6 +29,7 @@
byte decode_character(byte chr);
byte encode_ascii(char chr);
int get_tile_number(int x, int y);
int get_tile_number_with_offset(int x, int y);
int ascii_strlen(char *str);
int wrapper_count_pixels_to_tiles(byte *str, int length);
int count_pixels_to_tiles(byte *str, int length, int startingPos);
@ -102,7 +103,8 @@ int setNumber_getLength(int value, byte *str, int maxLength);
int print_string_in_buffer(byte *str, int x, int y, int *dest);
void printCashWindow();
WINDOW* getWindow(int index);
void printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
void printTinyArrow(int x, int y);
int printstr_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
unsigned short printstr_hlight_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
unsigned short printstr_hlight_pixels_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
@ -122,7 +124,9 @@ extern byte m2_cstm_last_printed[];
extern byte *m2_script_readability;
extern int overworld_buffer;
extern PC m2_ness_data[];
extern int m2_arrow_tile[];
extern bool m2_isequipped(int item_index);
extern void cpufastset(void *source, void *dest, int mode);
extern byte* m2_strlookup(int *offset_table, byte *strings, int index);
extern void m2_formatnumber(int value, byte* strDest, int length);

View File

@ -62,6 +62,7 @@ mov r3,6
//.org 0x80B8A3C :: bl print_window_with_buffer
.org 0x80B8890 :: bl print_window_with_buffer :: bl b8894_printCashWindowAndStore //Main window + Cash Window out of Status menu
.org 0x80B8664 :: bl print_window_with_buffer :: bl b8894_printCashWindowAndStore //Main window + Cash Window out of PSI menu
.org 0x80B8740 :: bl print_window_with_buffer :: bl b8894_printCashWindowAndStore //Main window + Cash Window out of Equip menu
.org 0x80B831A :: bl initWindow_buffer
.org 0x80B8320 :: bl b8320_statusWindowTextStore
@ -166,40 +167,136 @@ mov r3,6
// Equip window generic hacks
//---------------------------------------------------------
.org 0x80BB02C :: bl innerEquipInput
.org 0x80B8066 :: bl printstr_hlight_buffer
.org 0x80B8074 :: mov r3,#0x12
.org 0x80B80A6 :: mov r3,#0x0D
.org 0x80B8092 :: bl initWindow_buffer //Initialize equipment window
.org 0x80B8098 :: bl print_window_with_buffer
.org 0x80B80BE :: bl initWindow_buffer
.org 0x80B80C4 :: bl printEquipWindowNumberText
.org 0x80B80EA :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip //Offense Number
.org 0x80B8112 :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip //Defense Number
.org 0x80B8138 :: bl initWindow_buffer
.org 0x80B813E :: bl print_window_with_buffer
.org 0x80B814A :: bl equipPrint
.org 0x80B8152 :: bl innerEquipInput
.org 0x80B81A2 :: bl initWindow_buffer
.org 0x80B81A8 :: bl print_window_with_buffer
.org 0x80B81BC :: bl equipPrint
.org 0x80B81CC :: bl print_equip_base_numbers
.org 0x80BAF96 :: bl initWindow_buffer //Go to inner window from outer window
.org 0x80BAF9C :: bl baf9c_print_window_store_buffer
.org 0x80BAFE6 :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip //Offense Number
.org 0x80BB00C :: mov r2,#0x37
.org 0x80BB17C :: bl equippableReadInput
.org 0x80BB198 :: bl printEquipNumbersArrow :: bl store_pixels_overworld :: b 0x80BB1AE //Offense Number
.org 0x80BB1A6 :: mov r2,#0x4C :: mov r3,#0x13 :: bl bb1aa_printnumberequip_store //Defense Number
.org 0x80BB05E :: bl initWindow_buffer
.org 0x80BB066 :: bl print_window_with_buffer
.org 0x80BB08A :: nop :: nop //Remove highlighting
.org 0x80BB0A8 :: bl initWindow_buffer
.org 0x80BB24C :: bl initWindow_buffer //Go back to outer window - Also does going back to inner (not innermost) window from weapons - not touched equipment
.org 0x80BB254 :: bl print_window_with_buffer
.org 0x80BB2C2 :: bl initWindow_buffer
.org 0x80BB2CA :: bl print_window_with_buffer
.org 0x80BB2E0 :: bl initWindow_buffer
.org 0x80BB2E8 :: bl print_window_with_buffer
.org 0x80BB2F6 :: bl equipPrint
.org 0x80BB300 :: bl innerEquipInput
.org 0x80BB33C :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BB36C :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
.org 0x80BB3FC :: bl initWindow_buffer //Go back to inner (not innermost) window from weapons - removed equipment
.org 0x80BB404 :: bl print_window_with_buffer
.org 0x80BB41A :: bl initWindow_buffer
.org 0x80BB422 :: bl print_window_with_buffer
.org 0x80BB430 :: bl equipPrint
.org 0x80BB43A :: bl innerEquipInput
.org 0x80BB476 :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BB4A6 :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
.org 0x80BB532 :: bl initWindow_buffer //Go back to inner (not innermost) window from weapons - equipped a weapon
.org 0x80BB53A :: bl print_window_with_buffer
.org 0x80BB550 :: bl initWindow_buffer
.org 0x80BB558 :: bl print_window_with_buffer
.org 0x80BB566 :: bl equipPrint
.org 0x80BB570 :: bl innerEquipInput
.org 0x80BB5AC :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BB5DC :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
.org 0x80BB9E4 :: bl initWindow_buffer //Go back to inner (not innermost) window from defensive equipment - not touched equipment
.org 0x80BB9EC :: bl print_window_with_buffer
.org 0x80BBA02 :: bl initWindow_buffer
.org 0x80BBA0A :: bl print_window_with_buffer
.org 0x80BBA18 :: bl equipPrint
.org 0x80BBA22 :: bl innerEquipInput
.org 0x80BBA5E :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BBA8E :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
.org 0x80BBB2C :: bl initWindow_buffer //Go back to inner (not innermost) window from defensive equipment - removed equipment
.org 0x80BBB34 :: bl print_window_with_buffer
.org 0x80BBB4A :: bl initWindow_buffer
.org 0x80BBB52 :: bl print_window_with_buffer
.org 0x80BBB60 :: bl equipPrint
.org 0x80BBB6A :: bl innerEquipInput
.org 0x80BBBA6 :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BBBD6 :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
.org 0x80BBC8A :: bl initWindow_buffer //Go back to inner (not innermost) window from defensive equipment - equipped something
.org 0x80BBC92 :: bl print_window_with_buffer
.org 0x80BBCA8 :: bl initWindow_buffer
.org 0x80BBCB0 :: bl print_window_with_buffer
.org 0x80BBCBE :: bl equipPrint
.org 0x80BBCC8 :: bl innerEquipInput
.org 0x80BBD04 :: mov r2,#0x37 :: mov r3,#3 :: bl printNumberEquip
.org 0x80BBD34 :: mov r2,#0x37 :: mov r3,#0x13 :: bl printNumberEquip
//When first entering the innermost menu
.org 0x80BB6E0 :: mov r2,#0x54 :: mov r3,#3 :: bl printNumberEquip //Change second offense number's position - Weapon
.org 0x80BB710 :: mov r2,#0x54 :: mov r3,#0x13 :: bl bb1aa_printnumberequip_store //Change second defense number's position - Weapon
.org 0x80BB820 :: mov r2,#0x54 :: mov r3,#0x13 :: bl printNumberEquip //Change second defense number's position - Body
.org 0x80BB950 :: mov r2,#0x54 :: mov r3,#0x13 :: bl printNumberEquip //Change second defense number's position - Arms
.org 0x80BBE8E :: mov r2,#0x54 :: mov r3,#0x13 :: bl printNumberEquip //Change second defense number's position - Other
.org 0x80BBEBE :: mov r2,#0x54 :: mov r3,#3 :: bl bb1aa_printnumberequip_store //Change second offense number's position - Other
//When changing selection in the innermost menu
.org 0x80BBDF0 :: mov r2,#0x54 :: mov r3,#0x13 :: bl printNumberEquip //Change second defense number's position - Defensive Equipment
.org 0x80BBE20 :: mov r2,#0x54 :: mov r3,#3 :: bl bb1aa_printnumberequip_store //Change second offense number's position - Defensive Equipment
//---------------------------------------------------------
// BAEF8 hacks (equip window)
//---------------------------------------------------------
// Erase offense change
.macro erase_offense
mov r0,0xC
.macro erase_offense_buffer
mov r0,0xB
mov r1,0xB
mov r2,4
bl print_blankstr
bl bb21c_print_blankstr_buffer
.endmacro
.macro erase_defense
mov r0,0xC
.macro erase_defense_buffer
mov r0,0xB
mov r1,0xD
mov r2,4
bl print_blankstr
bl bb21c_print_blankstr_buffer
.endmacro
.org 0x80BB216 :: erase_offense
.org 0x80BB38C :: erase_offense
.org 0x80BB4C6 :: erase_offense
.org 0x80BB5FC :: erase_offense
.org 0x80BBAAE :: erase_offense
.org 0x80BBBF6 :: erase_offense
.org 0x80BBD54 :: erase_offense
.macro erase_defense_buffer_store
mov r0,0xB
mov r1,0xD
mov r2,4
bl bb21c_print_blankstr_buffer_store
.endmacro
.org 0x80BB216 :: erase_offense_buffer
.org 0x80BB38C :: erase_offense_buffer
.org 0x80BB4C6 :: erase_offense_buffer
.org 0x80BB5FC :: erase_offense_buffer
.org 0x80BBAAE :: erase_offense_buffer
.org 0x80BBBF6 :: erase_offense_buffer
.org 0x80BBD54 :: erase_offense_buffer
// Erase defense change
.org 0x80BB226 :: erase_defense
.org 0x80BBABE :: erase_defense
.org 0x80BBC06 :: erase_defense
.org 0x80BBD64 :: erase_defense
.org 0x80BB226 :: erase_defense_buffer
.org 0x80BBABE :: erase_defense_buffer_store
.org 0x80BBC06 :: erase_defense_buffer_store
.org 0x80BBD64 :: erase_defense_buffer_store
// Erase offense/defense after changing equipment
.org 0x80BB3E2 :: bl baef8_reequip_erase
@ -500,7 +597,8 @@ pop {pc}
//---------------------------------------------------------
.org 0x80CABF8 :: push {r4-r7,lr}
.org 0x80CAC0C
.org 0x80CAC0A
mov r6,1
mov r7,0
add sp,-4
b @@print_checkerboard_check

View File

@ -225,6 +225,49 @@ pop {r7,pc}
.pool
//==============================================================================
//Print numbers in the numbers window at the beginning - Used in order to make sure the one-person version prints the numbers
print_equip_base_numbers:
push {lr}
add sp,#-4
bl 0x80BC034
lsl r0,r0,#0x18
lsr r0,r0,#0x18
mov r1,r8
mov r2,#3
bl m2_formatnumber
mov r5,#0
mov r0,r10
strb r5,[r0,#0x15]
mov r0,#0xFF
mov r1,r10
strb r0,[r1,#0x16]
ldr r0,[r4,#0x14]
str r5,[sp]
mov r1,r8
mov r2,#0x37
mov r3,#3
bl printnumberequip //Prints Offense number
bl 0x80BC0CC
lsl r0,r0,#0x18
lsr r0,r0,#0x18
mov r1,r8
mov r2,#3
bl m2_formatnumber
mov r0,r10
strb r5,[r0,#0x15]
mov r0,#0xFF
mov r1,r10
strb r0,[r1,#0x16]
ldr r0,[r4,#0x14]
str r5,[sp]
mov r1,r8
mov r2,#0x37
mov r3,#0x13
bl printnumberequip //Prints Defense number
bl store_pixels_overworld
add sp,#4
pop {pc}
//==============================================================================
// Clears the equipment portion of the equip window
// r0 = window pointer
@ -258,11 +301,11 @@ push {r0-r3}
mov r0,8
mov r1,0xB
mov r2,8
bl print_blankstr
bl bb21c_print_blankstr_buffer
mov r0,8
mov r1,0xD
mov r2,8
bl print_blankstr
bl bb21c_print_blankstr_buffer
pop {r0-r3}
// Clobbered code
@ -279,11 +322,11 @@ push {r0-r3}
mov r0,8
mov r1,0xB
mov r2,8
bl print_blankstr
bl bb21c_print_blankstr_buffer
mov r0,8
mov r1,0xD
mov r2,8
bl print_blankstr
bl bb21c_print_blankstr_buffer
pop {r0-r3}
// Clobbered code
@ -309,7 +352,7 @@ push {r0-r3,lr}
mov r0,5
mov r1,0xF
mov r2,0x14
bl print_blankstr
bl bb21c_print_blankstr_buffer
pop {r0-r3,pc}
//==============================================================================
@ -448,7 +491,7 @@ beq @@next
// If flag 0x10 is set, clear the PSI window
ldr r0,[r5,0x1C] // PSI window
ldr r1,=#0x2012000
ldr r1,=#overworld_buffer - 0x2000
bl clear_window_buffer
@@next:
@ -462,14 +505,16 @@ pop {pc}
// Clear offense/defense when re-equipping (or un-equipping) something
baef8_reequip_erase:
push {r0-r3,lr}
mov r0,8
mov r0,7
mov r1,0xB
mov r2,4
bl print_blankstr
mov r0,8
ldr r3,=#overworld_buffer - 0x2000
bl print_blankstr_buffer
mov r0,7
mov r1,0xD
mov r2,4
bl print_blankstr
ldr r3,=#overworld_buffer - 0x2000
bl print_blankstr_buffer
// Clobbered code
pop {r0-r3}
@ -706,7 +751,7 @@ ldrh r0,[r0]
cmp r0,0
beq @@next
ldr r0,=#0x3005230
ldr r1,=#0x2012000
ldr r1,=#overworld_buffer - 0x2000
ldr r0,[r0,0x1C]
bl clear_window_buffer
@ -2016,6 +2061,14 @@ bx r0 //Jump to the next useful piece of code
.pool
//==============================================================================
//Calls print_window_with_buffer and then stores the buffer
baf9c_print_window_store_buffer:
push {lr}
bl print_window_with_buffer
bl store_pixels_overworld
pop {pc}
//==============================================================================
//Fixes issue with sounds when going from the PSI window to the inner PSI window
b8d40_psi_going_inner_window:
@ -2253,7 +2306,7 @@ orr r2,r1
strb r2,[r4,#0x3]
mov r3,r0
mov r0,r4
ldr r1,=#0x2012000
ldr r1,=#overworld_buffer - 0x2000
mov r4,r3
bl clear_window_buffer
mov r0,r4
@ -2442,7 +2495,7 @@ push {lr}
ldr r1,=#m2_active_window_pc
ldrb r1,[r1,#0]
push {r1} //Stores the active_window_pc
bl 0x80C4EB0 //Input management function
bl equipReadInput //Input management function
pop {r1}
cmp r0,#0 //Has an action happened? (Are we entering/exiting the menu?)
beq @@check_character_change
@ -2526,6 +2579,35 @@ bx r0
.pool
//==============================================================================
//Prints defense number and then sotres the buffer
bb1aa_printnumberequip_store:
push {r4,lr}
mov r4,r3
mov r3,#0
push {r3}
mov r3,r4
bl printNumberEquip
bl store_pixels_overworld
pop {r3}
pop {r4,pc}
//==============================================================================
//Prints blankstr in the buffer
bb21c_print_blankstr_buffer:
push {lr}
ldr r3,=#overworld_buffer - 0x2000
bl print_blankstr_buffer
pop {pc}
//==============================================================================
//Prints blankstr in the buffer and stores it
bb21c_print_blankstr_buffer_store:
push {lr}
ldr r3,=#overworld_buffer - 0x2000
bl print_blankstr_buffer
bl store_pixels_overworld
pop {pc}
//==============================================================================
//Set things up so the numbers for Offense and Defense for the innermost equipment window is only printed when needed
@ -2538,7 +2620,7 @@ ldsh r2,[r0,r2] //Window's Y cursor
add r1,r1,r2
ldrb r1,[r1,#0] //Selected item
push {r1}
bl 0x80C5500 //Input management function - returns the currently selected item
bl equippableReadInput //Input management function - returns the currently selected item
pop {r1}
cmp r1,r0 //Has the currently selected item changed?
bne @@refresh
@ -2644,14 +2726,14 @@ bx r0
//Clears the rightmost part of the Offense/Defense window for the innermost equipment menu
clear_offense_defense_inner_equip:
push {lr}
mov r0,0xD
mov r0,0xC
mov r1,0xB
mov r2,0x3
bl print_blankstr
mov r0,0xD
bl bb21c_print_blankstr_buffer
mov r0,0xC
mov r1,0xD
mov r2,0x3
bl print_blankstr
bl bb21c_print_blankstr_buffer
pop {pc}
.pool

View File

@ -266,49 +266,49 @@
"OffsetLocation": 11632508,
"OldPointer": 11630256,
"Old": " ぶき :[01 FF] ボディ:[01 FF] うで :[01 FF] そのた:[00 FF]",
"New": "[5F FF 08]Weapon:[01 FF][5F FF 08]Body:[01 FF][5F FF 08]Arms:[01 FF][5F FF 08]Other:[00 FF]"
"New": "[5F FF 0E]Weapon[01 FF][5F FF 1A]Body[01 FF][5F FF 17]Arms[01 FF][5F FF 17]Other[00 FF]"
},
{
"Index": 38,
"OffsetLocation": 11632512,
"OldPointer": 11630284,
"Old": "ぶき[00 FF]",
"New": "Weapon[00 FF]"
"New": "[5F FF 0E]Weapon[00 FF]"
},
{
"Index": 39,
"OffsetLocation": 11632516,
"OldPointer": 11630288,
"Old": "ボディ[00 FF]",
"New": "Body[00 FF]"
"New": "[5F FF 1A]Body[00 FF]"
},
{
"Index": 40,
"OffsetLocation": 11632520,
"OldPointer": 11630293,
"Old": "うで[00 FF]",
"New": "Arms[00 FF]"
"New": "[5F FF 17]Arms[00 FF]"
},
{
"Index": 41,
"OffsetLocation": 11632524,
"OldPointer": 11630297,
"Old": "そのた[00 FF]",
"New": "Other[00 FF]"
"New": "[5F FF 17]Other[00 FF]"
},
{
"Index": 42,
"OffsetLocation": 11632528,
"OldPointer": 11630302,
"Old": "(なし) [00 FF]",
"New": "(None)[00 FF]"
"New": "(Nothing)[00 FF]"
},
{
"Index": 43,
"OffsetLocation": 11632532,
"OldPointer": 11630314,
"Old": " オフェンス:[01 FF]ディフェンス:[00 FF]",
"New": "[5F FF 08]Offense:[01 FF][5F FF 08]Defense:[00 FF]"
"New": "Offense:[01 FF]Defense:[00 FF]"
},
{
"Index": 44,