diff --git a/build.ps1 b/build.ps1 index a59f039..f6e669d 100644 --- a/build.ps1 +++ b/build.ps1 @@ -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; diff --git a/src/c/battle.c b/src/c/battle.c index cb52650..7ebc742 100644 --- a/src/c/battle.c +++ b/src/c/battle.c @@ -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 } } } diff --git a/src/c/battle.h b/src/c/battle.h index d488701..813d7be 100644 --- a/src/c/battle.h +++ b/src/c/battle.h @@ -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 \ No newline at end of file diff --git a/src/c/equip.c b/src/c/equip.c new file mode 100644 index 0000000..8bb155a --- /dev/null +++ b/src/c/equip.c @@ -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); +} diff --git a/src/c/equip.h b/src/c/equip.h new file mode 100644 index 0000000..bc5449b --- /dev/null +++ b/src/c/equip.h @@ -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 \ No newline at end of file diff --git a/src/c/goods.h b/src/c/goods.h index 7c188eb..74dcb3f 100644 --- a/src/c/goods.h +++ b/src/c/goods.h @@ -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); diff --git a/src/c/vwf.c b/src/c/vwf.c index 0ad9327..a2acedb 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -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,10 +1255,21 @@ 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) { - x += print_character_formatted_buffer(decode_character(*str++), x, y, 0, 0xF, dest); - charCount++; + 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; @@ -1240,7 +1277,7 @@ int print_string_in_buffer(byte *str, int x, int y, int *dest) 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; diff --git a/src/c/vwf.h b/src/c/vwf.h index 671737f..ceef68c 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -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); diff --git a/src/m2-hack.asm b/src/m2-hack.asm index a39a69c..ec1e72b 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -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 diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index 19df094..06001ec 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -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 diff --git a/working/m12-misctext.json b/working/m12-misctext.json index deb7ed2..59ce428 100644 --- a/working/m12-misctext.json +++ b/working/m12-misctext.json @@ -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,