Add buffering for the full status window. Also update status tiles in printed text.
Temporarily breaks battle psi menu
This commit is contained in:
parent
1c0e1264e0
commit
310771a6a9
|
@ -15,7 +15,9 @@ $input_c_files =
|
|||
"src/c/vwf.c",
|
||||
"src/c/locs.c",
|
||||
"src/c/goods.c",
|
||||
"src/c/fileselect.c"
|
||||
"src/c/fileselect.c",
|
||||
"src/c/status.c",
|
||||
"src/c/psi.c"
|
||||
|
||||
$base_c_address = 0x8100000;
|
||||
$scripttool_cmd = "bin/ScriptTool/ScriptTool.dll"
|
||||
|
|
|
@ -13,6 +13,8 @@ int __attribute__((naked)) m2_remainder(int dividend, int divisor) {}
|
|||
void __attribute__((naked)) m2_formatnumber(int value, byte* strDest, int length) {}
|
||||
int __attribute__((naked)) m2_sub_a334c(int value) {}
|
||||
int __attribute__((naked)) m2_sub_a3384(int value) {}
|
||||
void __attribute__((naked)) m2_sub_d3c50() {}
|
||||
void __attribute__((naked)) m2_sub_d6844() {}
|
||||
int __attribute__((naked)) m2_clearwindowtiles(WINDOW* window) {}
|
||||
int __attribute__((naked)) customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, int* dest) {}
|
||||
void __attribute__((naked)) m2_printstr(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight) {}
|
||||
|
|
|
@ -189,7 +189,7 @@ void print_file_string(int x, int y, int length, byte *str, int window_selector,
|
|||
fileselect_pixels_location,
|
||||
&get_tile_number_file_select,
|
||||
tilesetDestPtr,
|
||||
width);
|
||||
width, 0x10);
|
||||
|
||||
pixelX += pixels;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,6 @@ typedef enum DIRECTION_MOVED
|
|||
DIRECTION_LEFT
|
||||
} MOVED;
|
||||
|
||||
typedef enum GOODS_ACTION
|
||||
{
|
||||
ACTION_NONE = 0,
|
||||
ACTION_STEPIN = 1,
|
||||
ACTION_STEPOUT = -1
|
||||
} GOODS_ACTION;
|
||||
|
||||
int goods_outer_process(WINDOW* window, int y_offset, bool give);
|
||||
int goods_inner_process(WINDOW *window, unsigned short *items);
|
||||
void goods_print_items(WINDOW *window, unsigned short *items, int y_offset);
|
||||
|
|
45
src/c/locs.c
45
src/c/locs.c
|
@ -1,22 +1,27 @@
|
|||
#include "locs.h"
|
||||
|
||||
int *fileselect_pixels_location = (int*) 0x2015000;
|
||||
int *window_flags = (int*) 0x300130C;
|
||||
PC (*pc_stats)[4] = (PC(*)[4]) 0x3001D54;
|
||||
byte *pc_count = (byte*) 0x3001F0B;
|
||||
bool (*pc_flags)[4] = (bool(*)[4]) 0x3001F0C;
|
||||
byte *pc_names = (byte*) 0x3001F10;
|
||||
PAD_STATE *pad_state = (PAD_STATE*) 0x3002500;
|
||||
PAD_STATE *pad_state_shadow = (PAD_STATE*) 0x3002504;
|
||||
unsigned short *tile_offset = (unsigned short*) 0x30051EC;
|
||||
int *first_window_flag = (int*) 0x30051F0;
|
||||
unsigned short *palette_mask = (unsigned short*) 0x3005228;
|
||||
WINDOW **window_pointers = (WINDOW**) 0x3005230;
|
||||
short *active_window_party_member = (short*) 0x3005264;
|
||||
unsigned short **tilemap_pointer = (unsigned short**)0x3005270;
|
||||
int *vram = (int*) 0x6000000;
|
||||
int *m2_misc_offsets = (int*) 0x8B17EE4;
|
||||
byte *m2_misc_strings = (byte*) 0x8B17424;
|
||||
int *m2_items_offsets = (int*) 0x8B1AF94;
|
||||
byte *m2_items_strings = (byte*) 0x8B1A694;
|
||||
unsigned short *name_header_tiles = (unsigned short*) 0x8B1B8B0;
|
||||
int *fileselect_pixels_location = (int*) 0x2015000;
|
||||
int *window_flags = (int*) 0x300130C;
|
||||
byte *character_general_data = (byte*) 0x3001D40;
|
||||
PC (*pc_stats)[4] = (PC(*)[4]) 0x3001D54;
|
||||
int *cash_on_hand = (int*) 0x30023D0;
|
||||
byte *pc_count = (byte*) 0x3001F0B;
|
||||
bool (*pc_flags)[4] = (bool(*)[4]) 0x3001F0C;
|
||||
byte *pc_names = (byte*) 0x3001F10;
|
||||
PAD_STATE *pad_state = (PAD_STATE*) 0x3002500;
|
||||
PAD_STATE *pad_state_shadow = (PAD_STATE*) 0x3002504;
|
||||
byte *script_readability = (byte*) 0x3004F08;
|
||||
unsigned short *tile_offset = (unsigned short*) 0x30051EC;
|
||||
int *first_window_flag = (int*) 0x30051F0;
|
||||
byte **free_strings_pointers = (byte**) 0x3005200;
|
||||
unsigned short *palette_mask = (unsigned short*) 0x3005228;
|
||||
WINDOW **window_pointers = (WINDOW**) 0x3005230;
|
||||
short *active_window_party_member = (short*) 0x3005264;
|
||||
unsigned short **tilemap_pointer = (unsigned short**) 0x3005270;
|
||||
int *vram = (int*) 0x6000000;
|
||||
int *m2_misc_offsets = (int*) 0x8B17EE4;
|
||||
byte *m2_misc_strings = (byte*) 0x8B17424;
|
||||
int *m2_items_offsets = (int*) 0x8B1AF94;
|
||||
byte *m2_items_strings = (byte*) 0x8B1A694;
|
||||
unsigned short *name_header_tiles = (unsigned short*) 0x8B1B8B0;
|
||||
PSIPrintInfo *psi_print_info = (PSIPrintInfo*) 0x8B2A9C0;
|
||||
|
|
|
@ -5,16 +5,20 @@
|
|||
#include "pc.h"
|
||||
#include "input.h"
|
||||
#include "window.h"
|
||||
#include "psi.h"
|
||||
|
||||
extern int *window_flags;
|
||||
extern PC (*pc_stats)[4];
|
||||
extern int *cash_on_hand;
|
||||
extern byte *pc_count;
|
||||
extern bool (*pc_flags)[4];
|
||||
extern byte *pc_names;
|
||||
extern PAD_STATE *pad_state;
|
||||
extern PAD_STATE *pad_state_shadow;
|
||||
extern byte *script_readability;
|
||||
extern unsigned short *tile_offset;
|
||||
extern int *first_window_flag;
|
||||
extern byte **free_strings_pointers;
|
||||
extern unsigned short *palette_mask;
|
||||
extern WINDOW **window_pointers;
|
||||
extern short *active_window_party_member;
|
||||
|
@ -26,5 +30,7 @@ extern byte *m2_misc_strings;
|
|||
extern int *m2_items_offsets;
|
||||
extern byte *m2_items_strings;
|
||||
extern unsigned short *name_header_tiles;
|
||||
extern byte *character_general_data;
|
||||
extern PSIPrintInfo *psi_print_info;
|
||||
|
||||
#endif
|
||||
|
|
39
src/c/pc.h
39
src/c/pc.h
|
@ -12,17 +12,37 @@ typedef enum AILMENT
|
|||
NAUSEOUS = 4,
|
||||
POISONED = 5,
|
||||
SUNSTROKE = 6,
|
||||
SNIFFLING = 7,
|
||||
MASHROOMIZED = 8,
|
||||
POSSESSED = 9,
|
||||
HOMESICK = 0xA,
|
||||
SNIFFLING = 7
|
||||
} AILMENT;
|
||||
|
||||
typedef enum AILMENT2
|
||||
{
|
||||
MASHROOMIZED = 1,
|
||||
POSSESSED = 2
|
||||
} AILMENT2;
|
||||
|
||||
typedef enum AILMENT3
|
||||
{
|
||||
SLEEP = 1,
|
||||
CRYING = 2
|
||||
} AILMENT3;
|
||||
|
||||
typedef enum CHARACTER
|
||||
{
|
||||
NESS = 0,
|
||||
PAULA = 1,
|
||||
JEFF = 2,
|
||||
POO = 3
|
||||
} CHARACTER;
|
||||
|
||||
typedef struct PC {
|
||||
unsigned short goods[14];
|
||||
int experience;
|
||||
//0x20
|
||||
byte unknown[12];
|
||||
int level;
|
||||
short level;
|
||||
short unknown2a;
|
||||
//0x30
|
||||
unsigned short hp_max;
|
||||
unsigned short hp_current;
|
||||
byte hp_unknown[2]; // possibly a rolling flag + a fractional value
|
||||
|
@ -31,13 +51,14 @@ typedef struct PC {
|
|||
unsigned short pp_current;
|
||||
byte pp_unknown[2];
|
||||
unsigned short pp_rolling;
|
||||
//0x40
|
||||
AILMENT ailment;
|
||||
bool mashroomized;
|
||||
bool sleep;
|
||||
AILMENT2 ailment2;
|
||||
AILMENT3 ailment3;
|
||||
bool strange;
|
||||
bool cant_concentrate;
|
||||
bool homesick;
|
||||
byte unknown2[2];
|
||||
bool unknown2[2];
|
||||
byte offense_base;
|
||||
byte defense_base;
|
||||
byte speed_base;
|
||||
|
@ -46,6 +67,7 @@ typedef struct PC {
|
|||
byte vitality_base;
|
||||
byte iq_base;
|
||||
byte offense_effective;
|
||||
//0x50
|
||||
byte defense_effective;
|
||||
byte speed_effective;
|
||||
byte guts_effective;
|
||||
|
@ -53,6 +75,7 @@ typedef struct PC {
|
|||
byte vitality_effective;
|
||||
byte iq_effective;
|
||||
byte unknown3[11];
|
||||
//0x61
|
||||
byte equipment[4];
|
||||
byte unknown4[7];
|
||||
} PC;
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
#include "window.h"
|
||||
#include "psi.h"
|
||||
#include "number-selector.h"
|
||||
#include "locs.h"
|
||||
|
||||
void psiWindow_buffer(CHARACTER psiCharacter, PSIWindow typeOfWindow, PSIClasses printableClasses)
|
||||
{
|
||||
PC *char_data = &(m2_ness_data[psiCharacter]);
|
||||
PSIPrintInfo *printInfo;
|
||||
int level = 0;
|
||||
int thing2 = 0;
|
||||
byte *str = 0;
|
||||
byte *boolCmpWindowType = (byte*)(&(typeOfWindow));
|
||||
byte *boolCmpPrintableClasses = (byte*)(&(printableClasses));
|
||||
byte *address = (byte*)0x3000A00;
|
||||
WINDOW *window = getWindow(7);
|
||||
SpecialPSIFlag *SpecialPSIFlags = (SpecialPSIFlag*)(character_general_data + 0x22A);
|
||||
bool print[0x11];
|
||||
for(int i = 0; i < 0x11; i ++)
|
||||
print[i] = true;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
(*(address + i)) = 0;
|
||||
(*(address + i + 4)) = 0;
|
||||
(*(address + i + 8)) = 0;
|
||||
}
|
||||
|
||||
if(psiCharacter == POO && typeOfWindow.Classes_Window && printableClasses.Offense)
|
||||
{
|
||||
if(SpecialPSIFlags->Poo_Starstorm_Alpha)
|
||||
{
|
||||
printInfo = &(psi_print_info[20]);
|
||||
psiPrint_buffer(20 + 1, window, print[6 - 1], printInfo);
|
||||
print[6 - 1] = false;
|
||||
}
|
||||
if(SpecialPSIFlags->Poo_Starstorm_Omega)
|
||||
{
|
||||
printInfo = &(psi_print_info[21]);
|
||||
psiPrint_buffer(21 + 1, window, print[6 - 1], printInfo);
|
||||
print[6 - 1] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printInfo = &(psi_print_info[0]);
|
||||
for(int i = 0; printInfo->PSIID != 0; i++)
|
||||
{
|
||||
if(psiCharacter != JEFF)
|
||||
{
|
||||
int val = psiCharacter == POO ? 2 : psiCharacter;
|
||||
level = printInfo->levelLearnt[val];
|
||||
}
|
||||
|
||||
if(level != 0)
|
||||
{
|
||||
byte *boolCmpWindowTypePrintInfo = (byte*)(&(printInfo->windowType));
|
||||
if((*boolCmpWindowType) & (*boolCmpWindowTypePrintInfo))
|
||||
{
|
||||
if(char_data->level >= level)
|
||||
{
|
||||
byte *boolCmpPrintableClassesPrintInfo = (byte*)(&(printInfo->possibleClasses));
|
||||
if((*boolCmpPrintableClasses) & (*boolCmpPrintableClassesPrintInfo))
|
||||
{
|
||||
psiPrint_buffer(i + 1, window, print[printInfo->PSIID - 1], printInfo);
|
||||
print[printInfo->PSIID - 1] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printInfo = &(psi_print_info[i + 1]);
|
||||
}
|
||||
|
||||
if(psiCharacter == NESS && typeOfWindow.Character_Window && printableClasses.Other)
|
||||
{
|
||||
if(SpecialPSIFlags->Ness_Teleport_Alpha)
|
||||
{
|
||||
printInfo = &(psi_print_info[0x32]);
|
||||
psiPrint_buffer(0x32 + 1, window, print[0x11 - 1], printInfo);
|
||||
print[0x11 - 1] = false;
|
||||
}
|
||||
if(SpecialPSIFlags->Ness_Teleport_Beta)
|
||||
{
|
||||
printInfo = &(psi_print_info[0x33]);
|
||||
psiPrint_buffer(0x33 + 1, window, print[0x11 - 1], printInfo);
|
||||
print[0x11 - 1] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void psiTargetWindow_buffer(byte target)
|
||||
{
|
||||
WINDOW *window = getWindow(0x9); //Target Window
|
||||
PSIPrintInfo *printInfo = &(psi_print_info[target - 1]);
|
||||
byte *string_group1 = (byte*)(0x8B204E4);
|
||||
byte extract = (printInfo->PSIID);
|
||||
byte value = 0;
|
||||
byte value2 = 0;
|
||||
byte *str = 0;
|
||||
if(extract != 4)
|
||||
{
|
||||
value = (*(string_group1 + (printInfo->PSIPrintInfoID * 12)));
|
||||
value = (value * 0x64);
|
||||
value2 = (*(string_group1 + (printInfo->PSIPrintInfoID * 12) + 1));
|
||||
value2 = (value2 * 0x14);
|
||||
str = (byte*)(0x8B74390 + value + value2); //It doesn't use the pointer to the description the struct has but it obtains it like this...
|
||||
}
|
||||
else
|
||||
str = (byte*)(0x8B74390);
|
||||
printstr_hlight_buffer(window, str, 0, 0, 0);
|
||||
|
||||
str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x1B);
|
||||
printstr_buffer(window, str, 0, 1, 0);
|
||||
|
||||
value = (*(string_group1 + (printInfo->PSIPrintInfoID * 12) + 3));
|
||||
str = (window->number_text_area + 0x12);
|
||||
m2_formatnumber(value, str, 2);
|
||||
(*(window->number_text_area + 0x14)) = 0;
|
||||
(*(window->number_text_area + 0x15)) = 0xFF;
|
||||
printstr_buffer(window, str, 7, 1, 0);
|
||||
}
|
||||
|
||||
void psiPrint_buffer(byte value, WINDOW* window, bool printPSILine, PSIPrintInfo *printInfo)
|
||||
{
|
||||
byte *str = 0;
|
||||
byte *address = (byte*)0x3000A00;
|
||||
|
||||
if(printPSILine)
|
||||
{
|
||||
byte PSIID = printInfo->PSIID;
|
||||
str = (byte*)(0x8B74228 + (PSIID * 0x14));
|
||||
printstr_hlight_buffer(window, str, 0, printInfo->YPrinting << 1, 0);
|
||||
if(PSIID == 1)
|
||||
{
|
||||
str = (byte*)(m2_ness_name + (7 * 4) + (8 * 2)); //Go to Rockin's name
|
||||
print_string_in_buffer(str, 0x71, ((printInfo->YPrinting << 1) + window->window_y) << 3, (int*)(0x2014000 - 0x2000));
|
||||
}
|
||||
}
|
||||
|
||||
byte symbol = printInfo->symbol;
|
||||
str = (byte*)(0x8B1B904 + (symbol * 3));
|
||||
printstr_hlight_buffer(window, str, printInfo->XSymbol + 1, printInfo->YPrinting << 1, 0);
|
||||
int val = ((((printInfo->XSymbol - 9) >> 0x1F) + printInfo->XSymbol - 9) >> 1) + (printInfo->YPrinting << 2);
|
||||
(*(address + val)) = value;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef HEADER_PSI_INCLUDED
|
||||
#define HEADER_PSI_INCLUDED
|
||||
|
||||
#include "vwf.h"
|
||||
|
||||
typedef struct PSIClasses {
|
||||
bool Offense : 1;
|
||||
bool Recover : 1;
|
||||
bool Assist : 1;
|
||||
bool Other : 1;
|
||||
} PSIClasses;
|
||||
|
||||
typedef struct PSIWindow
|
||||
{
|
||||
bool Character_Window : 1;
|
||||
bool Classes_Window : 1;
|
||||
} PSIWindow;
|
||||
|
||||
typedef struct PSIPrintInfo {
|
||||
byte PSIID;
|
||||
byte symbol;
|
||||
PSIClasses possibleClasses;
|
||||
PSIWindow windowType;
|
||||
unsigned short PSIPrintInfoID;
|
||||
byte levelLearnt[3];
|
||||
byte XSymbol;
|
||||
unsigned short YPrinting;
|
||||
byte *description;
|
||||
} PSIPrintInfo;
|
||||
|
||||
typedef struct SpecialPSIFlag {
|
||||
bool Ness_Teleport_Alpha : 1;
|
||||
bool Poo_Starstorm_Alpha : 1;
|
||||
bool Poo_Starstorm_Omega : 1;
|
||||
bool Ness_Teleport_Beta : 1;
|
||||
} SpecialPSIFlag;
|
||||
|
||||
|
||||
void psiWindow_buffer(CHARACTER psiCharacter, PSIWindow typeOfWindow, PSIClasses printableClasses);
|
||||
void psiTargetWindow_buffer(byte target);
|
||||
void psiPrint_buffer(byte value, WINDOW* window, bool printPSILine, PSIPrintInfo *printInfo);
|
||||
|
||||
|
||||
extern PSIPrintInfo m2_psi_print_table[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,277 @@
|
|||
#include "window.h"
|
||||
#include "status.h"
|
||||
#include "number-selector.h"
|
||||
#include "locs.h"
|
||||
|
||||
void printNumberOfStatus(int maxLength, int value, int blankX, int y, int strX, int width)
|
||||
{
|
||||
byte str[0x10];
|
||||
int end = setNumber_getLength(value, str, maxLength);
|
||||
str[end] = 0;
|
||||
str[end + 1] = 0xFF;
|
||||
print_blankstr_buffer(blankX, y, width, (int*)(0x2014000 - 0x2000));
|
||||
int x = (strX - (end * 6));
|
||||
print_string_in_buffer(str, x, y << 3, (int*)(0x2014000 - 0x2000));
|
||||
}
|
||||
|
||||
void printStatusSymbolArrangement(unsigned short symbolTile, WINDOW* window)
|
||||
{
|
||||
unsigned short *arrangementBase = ((*tilemap_pointer) + (((window->window_y) + 2) << 5) + window->window_x);
|
||||
unsigned short ailmentTile = ((*tile_offset) + symbolTile) | (*palette_mask);
|
||||
(*(arrangementBase + 10)) = ailmentTile;
|
||||
if(symbolTile == 0x1FF)
|
||||
ailmentTile -= 0x20;
|
||||
(*(arrangementBase + 42)) = (ailmentTile + 0x20);
|
||||
}
|
||||
|
||||
void printStatusString(WINDOW* window, int value)
|
||||
{
|
||||
byte *str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, value);
|
||||
printstr_hlight_buffer(window, str, 1, 2, 0);
|
||||
}
|
||||
|
||||
int statusNumbersPrint(WINDOW* window, bool doNotPrint)
|
||||
{
|
||||
if ((!(window->flags_unknown3a & 0x10)) && !doNotPrint)
|
||||
{
|
||||
window->flags_unknown3a |= 0x10;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
if(!doNotPrint)
|
||||
{
|
||||
m2_hpwindow_up(*active_window_party_member);
|
||||
PC *character_data = &(m2_ness_data[*active_window_party_member]);
|
||||
printNumberOfStatus(2, character_data->level, 0x5, 1, 0x38, 3);
|
||||
printNumberOfStatus(3, character_data->hp_max, 0x10, 7, 0x93, 3);
|
||||
printNumberOfStatus(3, character_data->hp_rolling, 0xC, 7, 0x78, 3);
|
||||
printNumberOfStatus(3, character_data->pp_max, 0x10, 9, 0x93, 3);
|
||||
printNumberOfStatus(3, character_data->pp_rolling, 0xC, 9, 0x78, 3);
|
||||
printNumberOfStatus(7, character_data->experience, 0xC, 0xB, 0x93, 7);
|
||||
if(character_data->level < 99)
|
||||
{
|
||||
unsigned int *experienceLevelTable = (unsigned int*)0x8B1EC20;
|
||||
unsigned int experienceLevelUp = *(experienceLevelTable + ((*active_window_party_member) * 100) + character_data->level + 1);
|
||||
printNumberOfStatus(7, experienceLevelUp - character_data->experience, 2, 0xD, 0x3D, 6);
|
||||
}
|
||||
else
|
||||
print_blankstr_buffer(2, 0xD, 6, (int*)(0x2014000 - 0x2000));
|
||||
printNumberOfStatus(3, character_data->offense_effective, 0x19, 0x1, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->defense_effective, 0x19, 0x3, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->speed_effective, 0x19, 0x5, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->guts_effective, 0x19, 0x7, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->vitality_effective, 0x19, 0x9, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->iq_effective, 0x19, 0xB, 0xE1, 4);
|
||||
printNumberOfStatus(3, character_data->luck_effective, 0x19, 0xD, 0xE1, 4);
|
||||
print_blankstr_buffer(5, 0xF, 0x14, (int*)(0x2014000 - 0x2000));
|
||||
if((*active_window_party_member) != JEFF)
|
||||
{
|
||||
byte *str = m2_strlookup((int*)0x8B17EE4, (byte*)0x8B17424, 0x13);
|
||||
print_string_in_buffer(str, 0x2C, (0xF) << 3, (int*)(0x2014000 - 0x2000));
|
||||
}
|
||||
print_blankstr_buffer(1, 0x3, 0xA, (int*)(0x2014000 - 0x2000));
|
||||
unsigned short symbolTile = ailmentTileSetup(character_data, 0);
|
||||
if(symbolTile == 0)
|
||||
{
|
||||
printStatusSymbolArrangement(0x1FF, window);
|
||||
}
|
||||
if(character_data->ailment != CONSCIOUS)
|
||||
printStatusString(window, 0x7F + character_data->ailment);
|
||||
else if(character_data->ailment2 != CONSCIOUS)
|
||||
printStatusString(window, 0x86 + character_data->ailment2);
|
||||
else if(character_data->homesick)
|
||||
printStatusString(window, 0x89);
|
||||
if(character_data->ailment != CONSCIOUS || character_data->ailment2 != CONSCIOUS || character_data->ailment3 != CONSCIOUS || character_data->strange || character_data->cant_concentrate || character_data->unknown2[0])
|
||||
{
|
||||
if(symbolTile == 0)
|
||||
return 0;
|
||||
printStatusSymbolArrangement(symbolTile, window);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int statusReadInput(WINDOW* window)
|
||||
{
|
||||
unsigned short previousCharacter = *active_window_party_member;
|
||||
int currentCharacter = previousCharacter;
|
||||
PAD_STATE state = *pad_state;
|
||||
PAD_STATE state_shadow = *pad_state_shadow;
|
||||
|
||||
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;
|
||||
}
|
||||
m2_hpwindow_up(currentCharacter);
|
||||
clear_name_header(window);
|
||||
copy_name_header(window, currentCharacter);
|
||||
(*active_window_party_member) = currentCharacter;
|
||||
if(currentCharacter != previousCharacter)
|
||||
statusNumbersPrint(window, false);
|
||||
}
|
||||
|
||||
if(state_shadow.right || state_shadow.left)
|
||||
{
|
||||
if(state.right || state.left)
|
||||
{
|
||||
int flag = *window_flags;
|
||||
if(flag & 0x800)
|
||||
{
|
||||
if(currentCharacter != previousCharacter)
|
||||
m2_soundeffect(0x131);
|
||||
}
|
||||
else if(currentCharacter != previousCharacter)
|
||||
m2_soundeffect(0x12E);
|
||||
}
|
||||
window->hold = true;
|
||||
}
|
||||
else
|
||||
window->hold = false;
|
||||
|
||||
if(state.b || state.select)
|
||||
{
|
||||
m2_soundeffect(0x12E);
|
||||
window->counter = 0;
|
||||
return ACTION_STEPOUT;
|
||||
}
|
||||
else if(state.a || state.l)
|
||||
{
|
||||
m2_soundeffect(0x12D);
|
||||
if(currentCharacter != JEFF)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int statusWindowNumbers(WINDOW* window, bool doNotPrint)
|
||||
{
|
||||
if(statusNumbersPrint(window, doNotPrint) == 0)
|
||||
return 0;
|
||||
return statusReadInput(window);
|
||||
}
|
||||
|
||||
int statusWindowText(WINDOW* window)
|
||||
{
|
||||
if(window->redraw)
|
||||
buffer_drawwindow(window, (int*)(0x2014000 - 0x2000));
|
||||
if(window->loaded_code != 0 && ((*script_readability) == 0))
|
||||
{
|
||||
window->delay = 0;
|
||||
while(true)
|
||||
{
|
||||
while(window->text_y >= window->window_height || window->window_y + window->text_y > 0x1F)
|
||||
properScroll(window, (int*)(0x2014000 - 0x2000));
|
||||
byte *str = window->text_start + window->text_offset;
|
||||
if((*(str + 1)) == 0xFF)
|
||||
{
|
||||
int returnedLength = customcodes_parse_generic(*str, str, window, (int*)(0x2014000 - 0x2000));
|
||||
if(returnedLength != 0)
|
||||
{
|
||||
if(returnedLength < 0)
|
||||
returnedLength = 0;
|
||||
window->text_offset += returnedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((*str) == 1)
|
||||
{
|
||||
window->text_y += 2;
|
||||
window->text_x = 0;
|
||||
window->text_offset += 2;
|
||||
}
|
||||
else if((*str) == 0)
|
||||
{
|
||||
window->loaded_code = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
window->text_offset++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(window->text_x >= window->window_width || window->window_x + window->text_x > 0x1F)
|
||||
{
|
||||
window->text_y += 2;
|
||||
window->text_x = 0;
|
||||
}
|
||||
weld_entry_custom_buffer(window, str, 0, 0xF, (int*)(0x2014000 - 0x2000));
|
||||
window->text_offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef HEADER_STATUS_INCLUDED
|
||||
#define HEADER_STATUS_INCLUDED
|
||||
|
||||
#include "vwf.h"
|
||||
|
||||
void printNumberOfStatus(int maxLength, int value, int blankX, int y, int strX, int width);
|
||||
void printStatusSymbolArrangement(unsigned short symbolTile, WINDOW* window);
|
||||
void printStatusString(WINDOW* window, int value);
|
||||
int statusNumbersPrint(WINDOW* window, bool doNotPrint);
|
||||
int statusReadInput(WINDOW* window);
|
||||
int statusWindowNumbers(WINDOW* window, bool doNotPrint);
|
||||
int statusWindowText(WINDOW* window);
|
||||
|
||||
#endif
|
1181
src/c/vwf.c
1181
src/c/vwf.c
File diff suppressed because it is too large
Load Diff
17
src/c/vwf.h
17
src/c/vwf.h
|
@ -39,7 +39,7 @@ void print_special_character(int tile, int x, int y);
|
|||
void map_special_character(unsigned short tile, int x, int y);
|
||||
void map_tile(unsigned short tile, int x, int y);
|
||||
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
|
||||
int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth);
|
||||
int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth, byte doubleTileHeight);
|
||||
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);
|
||||
|
@ -92,6 +92,16 @@ int jumpToOffset(byte* character);
|
|||
void copy_tile_buffer(int xSource, int ySource, int xDest, int yDest, int *dest);
|
||||
void copy_tile_up_buffer(int x, int y, int *dest);
|
||||
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, int *dest);
|
||||
unsigned short ailmentTileSetup(PC *character, unsigned short defaultVal);
|
||||
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);
|
||||
unsigned short printstr_hlight_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
|
||||
|
||||
extern unsigned short m2_coord_table[];
|
||||
extern byte m2_ness_name[];
|
||||
|
@ -107,6 +117,7 @@ extern byte m12_other_str7[];
|
|||
extern byte m12_other_str8[];
|
||||
extern byte m2_cstm_last_printed[];
|
||||
extern byte *m2_script_readability;
|
||||
extern PC m2_ness_data[];
|
||||
|
||||
extern void cpufastset(void *source, void *dest, int mode);
|
||||
extern byte* m2_strlookup(int *offset_table, byte *strings, int index);
|
||||
|
@ -119,4 +130,6 @@ extern int m2_div(int dividend, int divisor);
|
|||
extern int m2_remainder(int dividend, int divisor);
|
||||
extern void m2_soundeffect(int index);
|
||||
extern void m2_printstr(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight);
|
||||
extern int customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, int* dest);
|
||||
extern int customcodes_parse_generic(int code, char* parserAddress, WINDOW* window, int* dest);
|
||||
extern void m2_sub_d3c50();
|
||||
extern void m2_sub_d6844();
|
|
@ -3,6 +3,13 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
typedef enum WINDOW_ACTION
|
||||
{
|
||||
ACTION_NONE = 0,
|
||||
ACTION_STEPIN = 1,
|
||||
ACTION_STEPOUT = -1
|
||||
} WINDOW_ACTION;
|
||||
|
||||
typedef struct WINDOW {
|
||||
// 0x00
|
||||
bool enable : 1; // 0x0001 Indicates that the window is enabled.
|
||||
|
@ -52,8 +59,8 @@ typedef struct WINDOW {
|
|||
unsigned short cursor_x_base;
|
||||
byte cursor_x_delta;
|
||||
byte unknown9a;
|
||||
byte loaded_code;
|
||||
byte unknown9[3];
|
||||
byte loaded_code;
|
||||
byte unknown9[3];
|
||||
int unknown10;
|
||||
int unknown11;
|
||||
} WINDOW;
|
||||
|
|
Binary file not shown.
|
@ -14,6 +14,7 @@
|
|||
//==============================================================================
|
||||
|
||||
.org 0x8AFED84 :: .incbin "data/m2-mainfont1-empty.bin"
|
||||
.org 0x8B03DE4 :: .incbin "data/m2-status-symbols.bin"
|
||||
.org 0x8B0F424 :: .incbin "data/m2-mainfont2-empty.bin"
|
||||
.org 0x8B13424 :: .incbin "data/m2-mainfont3-empty.bin"
|
||||
.org 0x8B088A4 :: .incbin "data/m2-shifted-cursor.bin"
|
||||
|
@ -49,17 +50,47 @@ mov r3,6
|
|||
.include "m2-status-initial.asm"
|
||||
.include "m2-status-switch.asm"
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Main window hacks
|
||||
//---------------------------------------------------------
|
||||
|
||||
.org 0x80B7D9A :: bl b7d9a_main_window_manage_input
|
||||
//.org 0x80B8A36 :: bl initWindow_buffer //Money window
|
||||
//.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 0x80B831A :: bl initWindow_buffer
|
||||
.org 0x80B8320 :: bl b8320_statusWindowTextStore
|
||||
|
||||
//---------------------------------------------------------
|
||||
// BAC18 hacks (status window)
|
||||
//---------------------------------------------------------
|
||||
|
||||
.org 0x80BACFC :: bl bac18_redraw_status
|
||||
.org 0x80BAC46 :: nop :: nop
|
||||
.org 0x80BAC6E :: bl bac6e_statusWindowNumbersInputManagement
|
||||
.org 0x80BAD7E :: bl printstr_buffer
|
||||
.org 0x80BAD88 :: bl initWindow_buffer
|
||||
.org 0x80BAD92 :: bl initWindow_buffer
|
||||
.org 0x80BACFC :: bl bac18_redraw_status_store
|
||||
.org 0x80BADE6 :: bl bac18_redraw_status
|
||||
.org 0x80BACEA :: bl bacea_status_psi_window
|
||||
.org 0x80BACBA :: bl print_window_with_buffer
|
||||
.org 0x80BACC4 :: bl initWindow_buffer
|
||||
.org 0x80BAD1A :: bl clearWindowTiles_buffer
|
||||
.org 0x80BADF6 :: bl initWindow_buffer
|
||||
.org 0x80BACEE :: bl bac18_clear_psi
|
||||
.org 0x80BADB0 :: bl badb0_status_inner_window
|
||||
.org 0x80BADCC :: b 0x80BADD8
|
||||
|
||||
//---------------------------------------------------------
|
||||
// PSI window hacks
|
||||
//---------------------------------------------------------
|
||||
|
||||
.org 0x80BAE1C :: bl print_window_with_buffer
|
||||
.org 0x80BAEC6 :: bl baec6_psi_window_print_buffer
|
||||
.org 0x80BAED4 :: bl baec6_psi_window_print_buffer
|
||||
.org 0x80BAEE2 :: bl baec6_psi_window_print_buffer
|
||||
.org 0x80BAEF0 :: bl baec6_psi_window_print_buffer
|
||||
|
||||
//---------------------------------------------------------
|
||||
// BAEF8 hacks (equip window)
|
||||
//---------------------------------------------------------
|
||||
|
@ -1511,12 +1542,15 @@ m2_coord_table_file:
|
|||
.definelabel m2_clearwindowtiles ,0x80CA834
|
||||
.definelabel m2_menuwindow ,0x80C1C98
|
||||
.definelabel m2_resetwindow ,0x80BE490
|
||||
.definelabel m2_sub_d3c50 ,0x80D3C50
|
||||
.definelabel m2_hpwindow_up ,0x80D3F0C
|
||||
.definelabel m2_curhpwindow_down ,0x80D41D8
|
||||
.definelabel m2_sub_d6844 ,0x80D6844
|
||||
.definelabel m2_div ,0x80F49D8
|
||||
.definelabel m2_remainder ,0x80F4A70
|
||||
.definelabel m2_default_names ,0x82B9330
|
||||
.definelabel m2_items ,0x8B1D62C
|
||||
.definelabel m2_default_names ,0x82B9330
|
||||
.definelabel m2_psi_print_table ,0x8B2A9C0
|
||||
|
||||
//==============================================================================
|
||||
// Code files
|
||||
|
|
|
@ -330,20 +330,50 @@ bl 0x80BE260
|
|||
mov r1,r0
|
||||
mov r0,r4
|
||||
mov r2,0
|
||||
bl 0x80BE458
|
||||
bl initWindow_buffer
|
||||
|
||||
// Render text
|
||||
mov r0,r4
|
||||
bl 0x80C8FFC
|
||||
bl statusWindowText
|
||||
|
||||
// Render numbers
|
||||
mov r0,r4
|
||||
ldrh r1,[r0,#0]
|
||||
ldr r2,=#0xFBFF
|
||||
and r1,r2
|
||||
strh r1,[r0,#0]
|
||||
mov r1,0
|
||||
bl 0x80C0A5C
|
||||
bl statusNumbersPrint
|
||||
|
||||
pop {r4,pc}
|
||||
.pool
|
||||
|
||||
//==============================================================================
|
||||
// Redraws the status window (when exiting the PSI menu) and stores it
|
||||
bac18_redraw_status_store:
|
||||
push {lr}
|
||||
bl bac18_redraw_status
|
||||
bl store_pixels_overworld
|
||||
pop {pc}
|
||||
.pool
|
||||
|
||||
//==============================================================================
|
||||
// Only if the character changed store the buffer - called when reading inputs
|
||||
bac6e_statusWindowNumbersInputManagement:
|
||||
push {lr}
|
||||
ldr r2,=#m2_active_window_pc
|
||||
ldrb r2,[r2,#0]
|
||||
push {r2}
|
||||
bl statusWindowNumbers
|
||||
pop {r2}
|
||||
ldr r1,=#m2_active_window_pc
|
||||
ldrb r1,[r1,#0]
|
||||
cmp r1,r2
|
||||
beq @@end
|
||||
bl store_pixels_overworld
|
||||
|
||||
@@end:
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
// Clears the PSI window when switching classes
|
||||
|
@ -359,7 +389,8 @@ beq @@next
|
|||
|
||||
// If flag 0x10 is set, clear the PSI window
|
||||
ldr r0,[r5,0x1C] // PSI window
|
||||
bl clear_window
|
||||
ldr r1,=#0x2012000
|
||||
bl clear_window_buffer
|
||||
|
||||
@@next:
|
||||
// Clobbered code
|
||||
|
@ -1761,7 +1792,6 @@ strb r2,[r0,#3]
|
|||
b @@end //Goes to the end of the routine
|
||||
|
||||
@@goToInner:
|
||||
bl load_pixels_overworld
|
||||
lsl r0,r0,0x10 //Properly stores the output into r4 and, since we're going into the inner window, sets vwf_skip to false
|
||||
asr r4,r0,0x10
|
||||
ldr r0,[r5,#0x20]
|
||||
|
@ -1884,7 +1914,7 @@ cmp r1,#0 //Checks if vwf_skip is false
|
|||
bne @@end
|
||||
mov r1,r2 //If it is, prints the PSI description
|
||||
mov r2,0
|
||||
bl m2_initwindow //Initializes the PSI description window
|
||||
bl initWindow_buffer //Initializes the PSI description window
|
||||
ldr r0,[r5,0x28]
|
||||
bl print_window_with_buffer //Prints the PSI description window
|
||||
bl store_pixels_overworld
|
||||
|
@ -2088,6 +2118,28 @@ pop {pc}
|
|||
|
||||
.pool
|
||||
|
||||
//==============================================================================
|
||||
//Prints and stores the PSI window in the PSI menu
|
||||
baec6_psi_window_print_buffer:
|
||||
push {lr}
|
||||
bl psiWindow_buffer
|
||||
bl store_pixels_overworld
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//Loads the buffer in if entering another window from the main window
|
||||
b7d9a_main_window_manage_input:
|
||||
push {lr}
|
||||
bl 0x80BE53C
|
||||
cmp r0,#0
|
||||
beq @@end
|
||||
cmp r0,#0
|
||||
blt @@end
|
||||
bl load_pixels_overworld
|
||||
|
||||
@@end:
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//Prints the target window if and only if the cursor's position changed in this input management function
|
||||
c495a_status_target:
|
||||
|
@ -2724,6 +2776,34 @@ pop {pc}
|
|||
|
||||
.pool
|
||||
|
||||
//==============================================================================
|
||||
//Prints the cash window and then stores the buffer to vram
|
||||
b8894_printCashWindowAndStore:
|
||||
push {lr}
|
||||
bl printCashWindow
|
||||
bl store_pixels_overworld
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//UNUSED
|
||||
bac46_statusWindowNumbersStore:
|
||||
push {lr}
|
||||
bl statusWindowNumbers
|
||||
bl store_pixels_overworld
|
||||
pop {pc}
|
||||
|
||||
//==============================================================================
|
||||
//Prints the status text and numbers in the buffer, then loads it in vram
|
||||
b8320_statusWindowTextStore:
|
||||
push {lr}
|
||||
push {r0}
|
||||
bl statusWindowText
|
||||
pop {r0}
|
||||
mov r1,#0
|
||||
bl statusNumbersPrint
|
||||
bl store_pixels_overworld
|
||||
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:
|
||||
|
@ -2733,7 +2813,7 @@ ldr r0,=#0x6002000 //Source
|
|||
str r0,[r1]
|
||||
ldr r0,=#0x2014000 //Target
|
||||
str r0,[r1,#4]
|
||||
ldr r0,=#0xA4001000 //Store 0x4000 bytes - When VBlank and in words of 32 bits
|
||||
ldr r0,=#0xA4001000 //Store 0x4000 bytes - When HBlank and in words of 32 bits
|
||||
str r0,[r1,#8]
|
||||
ldr r0,[r1,#8]
|
||||
pop {r0-r1,pc}
|
||||
|
|
Loading…
Reference in New Issue