From fab36711c2ee5dc0f624c6fd9417b6395a29f2ff Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Fri, 9 Aug 2019 02:13:35 +0200 Subject: [PATCH 1/8] Add Alphabet cursoring and character selection --- src/c/vwf.c | 247 +++++++++++++++++++++++++++++++-- src/c/vwf.h | 1 + src/data/m2-alphabet-table.bin | Bin 0 -> 292 bytes src/m2-hack.asm | 5 + 4 files changed, 245 insertions(+), 8 deletions(-) create mode 100644 src/data/m2-alphabet-table.bin diff --git a/src/c/vwf.c b/src/c/vwf.c index c195354..5257537 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -22,8 +22,8 @@ int get_tile_number(int x, int y) { x--; y--; - if(y > 0xF) - y = 0xE + (y & 1); + if(y > 0xF) + y = 0xE + (y & 1); return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32; //This is... Very not suited for tilemaps of variable width, which can have more than 0x10 tiles vertically. } @@ -114,14 +114,14 @@ void wrapper_name_summary_string(int x, int y, int length, byte *str, int window int count_pixels(byte *str, int length) { - int pixels = 0; + int pixels = 0; for(int i = 0; i < length; i++) - if((str[i] != 0xFF) && (str[i] != 0xFE)) //The latter one is not really needed + if((str[i] != 0xFF) && (str[i] != 0xFE)) //The latter one is not really needed pixels += (m2_widths_table[0][decode_character(str[i])] & 0xFF); - int tiles = pixels >> 3; - if((pixels & 7) != 0) - tiles +=1; - return tiles; + int tiles = pixels >> 3; + if((pixels & 7) != 0) + tiles +=1; + return tiles; } void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector) @@ -199,6 +199,237 @@ void print_file_string(int x, int y, int length, byte *str, int window_selector, *palette_mask = realmask; } +unsigned short setupCursorAction(int *Pos1, int *Pos2) +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + int alphabet = caller[0xDAC >> 2]; + int *table = (int *)0x82B8FFC; //Address of the alphabet table + + int choice = 0; + int counter = 0; + + for(int i = 0; i < CursorY; i++) + { + if(i <= 4) + choice += 0xE; + else + choice += 3; + } + + choice += CursorX; + (*Pos1) = alphabet; + (*Pos2) = choice; + + unsigned short letter = (table[choice] >> (16 * alphabet)); + return letter; +} + +void setupCursorMovement() +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + int yAxys = 0; + int xAxys = 0; + + // Check for pressing left or right + PAD_STATE state = *pad_state; + + if (state.right) + xAxys = 1; + else if (state.left) + xAxys = -1; + else if (state.up) + yAxys = -1; + else if(state.down) + yAxys = 1; + + if(xAxys != 0) + { + CursorX += xAxys; + switch(CursorY) + { + case 0: + case 1: + case 2: + if(CursorX < 0) + CursorX = 0xA; + if(CursorX > 0xA) + CursorX = 0; + break; + case 3: + if(CursorX < 0) + CursorX = 0xB; + if(CursorX > 0xB) + CursorX = 0; + break; + case 4: + if(CursorX < 0) + CursorX = 0x3; + if(CursorX > 0x3) + CursorX = 0; + break; + default: + if(CursorX < 0) + CursorX = 0x2; + if(CursorX > 0x2) + CursorX = 0; + break; + } + m2_soundeffect(0x1A7); + } + else if(yAxys != 0) + { + switch(CursorY) + { + case 0: + case 1: + case 2: + CursorY += yAxys; + if(CursorY < 0) + { + if((CursorX >= 0x9)) + { + CursorX = 2 + CursorX - 0x9; + CursorY = 4; + } + else if(CursorX == 0) + CursorY = 5; + else + CursorY = 3; + } + else if(CursorY == 3 && CursorX >= 0x9) + CursorX += 1; + break; + case 3: + CursorY += yAxys; + if(CursorY == 2 && CursorX >= 9) + CursorX -=1; + if(CursorY == 4) + { + if(CursorX <= 3) + CursorX = 0; + else if (CursorX <= 9) + CursorX = 1; + else + CursorX = 2 + CursorX - 0xA; + } + break; + case 4: + CursorY += yAxys; + if(CursorY == 3) + { + if(CursorX >= 2) + CursorX = 0xA + CursorX - 2; + if(CursorX == 1) + CursorX = 4; + } + if(CursorY == 5) + { + if(CursorX >= 2) + CursorX = 1; + else + CursorX = 0; + } + break; + default: + CursorY += yAxys; + if(CursorY == 4 && CursorX == 2) + CursorX = 3; + if(CursorY == 6) + { + if(CursorX == 0) + CursorY = 0; + else + CursorY = 5; + } + break; + } + m2_soundeffect(0x1A8); + } + + caller[0xDA4 >> 2] = CursorX; + caller[0xDA8 >> 2] = CursorY; +} + +void setupCursorPosition(int *x, int *y) +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + (*x) = 0; + (*y) = 0; + if(CursorY <= 4) + { + (*y) = 2 + (CursorY << 1); + switch(CursorY) + { + case 0: + case 1: + case 2: + switch(CursorX) + { + case 9: + case 0xA: + (*x) = 23 + ((CursorX -9) << 1); + break; + default: + (*x) = 1 + (CursorX << 1); + break; + } + break; + case 3: + switch(CursorX) + { + case 0xA: + case 0xB: + (*x) = 23 + ((CursorX -0xA) << 1); + break; + default: + (*x) = 1 + (CursorX << 1); + break; + } + break; + default: + switch(CursorX) + { + case 0: + (*x) = 1; + break; + case 1: + (*x) = 8; + break; + case 2: + case 3: + (*x) = 23 + ((CursorX- 2) << 1); + break; + } + break; + } + } + else + { + (*y) = 14; + switch(CursorX) + { + case 0: + (*x) = 1; + break; + case 1: + (*x) = 18; + break; + default: + (*x) = 26; + break; + } + } +} + void format_options_cc(char String[], int *index, byte cmd) { String[(*index)++] = 0xFE; diff --git a/src/c/vwf.h b/src/c/vwf.h index 77539e4..4e28bed 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -93,3 +93,4 @@ extern int m2_resetwindow(WINDOW* window, bool skip_redraw); extern void m2_hpwindow_up(int character); extern int m2_div(int dividend, int divisor); extern int m2_remainder(int dividend, int divisor); +extern void m2_soundeffect(int index); \ No newline at end of file diff --git a/src/data/m2-alphabet-table.bin b/src/data/m2-alphabet-table.bin new file mode 100644 index 0000000000000000000000000000000000000000..a91773eb7e9b2c0e03ffc5495b3f22fce7e7ebed GIT binary patch literal 292 zcma*U$8v#T0EW@$5@js1B1B&qL`{_F>_qPp-59P9! zL60PTQVd8l#G!Vz$}r-cF&|9GG9|~1JaY;x_~e@+KRoM6tx7B@v!cS9DjRBSsk5WO wo+bxu>eLsta^b?Quj)~+`qZxh4QfcA^r(M~d6>H~CQO*K{@2ai%vCS?3tFK<9smFU literal 0 HcmV?d00001 diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 7831544..49233a7 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1124,6 +1124,11 @@ nop .org 0x8004EA2 :: bl _4092_print_window //Printing .org 0x82B7A8C :: dw 0x86DB5C4 .org 0x86DB5C4 :: .incbin "data/m2-alphabet-template.bin" +.org 0x8005222 :: bl setupCursorAction +.org 0x8005382 :: bl setupCursorMovement +.org 0x800538A :: bl setupCursorPosition //Cursor position +.org 0x800536C :: bl setupCursorPosition //Cursor position +.org 0x82B8FFC :: .incbin "data/m2-alphabet-table.bin" //Summary .org 0x80055B0 :: bl _4092_print_window //Printing From a94b8c25400d7bfc24673c734d8eb73400c47d43 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Fri, 9 Aug 2019 04:23:11 +0200 Subject: [PATCH 2/8] Fix issue not visible on no$gba caused by memcopy right before printing Ness' description --- src/c/vwf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/c/vwf.c b/src/c/vwf.c index 5257537..01f9c0d 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -846,6 +846,8 @@ void print_windows(int window_selector) case 0x8: //FavFood's name + description case 0x9: //FavThing's name + description if((m2_cstm_last_printed[0] & 0x1F) != window_selector){ + if(window_selector == 3) + m2_cstm_last_printed[0] = window_selector; //Set the alphabet bits to 0. Fixes issue where random garbage would go in here when transitioning screen from the main menu. offset = 0x1800; description_setup(String, window_selector); print_file_string(9, 1, 0x40, String, window_selector, offset); From d4a9aa1b44e3860fb1e668b3dfae4703cea280df Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Fri, 9 Aug 2019 16:03:37 +0200 Subject: [PATCH 3/8] Fix random memory issue for good Previous commit could have been fooled if a value containing a 3 was copied. This commit ensures that cannot happen. --- src/c/vwf.c | 4 +--- src/m2-hack.asm | 1 + src/m2-vwf-entries.asm | 13 ++++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/c/vwf.c b/src/c/vwf.c index 01f9c0d..faed979 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -846,9 +846,7 @@ void print_windows(int window_selector) case 0x8: //FavFood's name + description case 0x9: //FavThing's name + description if((m2_cstm_last_printed[0] & 0x1F) != window_selector){ - if(window_selector == 3) - m2_cstm_last_printed[0] = window_selector; //Set the alphabet bits to 0. Fixes issue where random garbage would go in here when transitioning screen from the main menu. - offset = 0x1800; + offset = 0x1800; description_setup(String, window_selector); print_file_string(9, 1, 0x40, String, window_selector, offset); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 49233a7..7039735 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1129,6 +1129,7 @@ nop .org 0x800538A :: bl setupCursorPosition //Cursor position .org 0x800536C :: bl setupCursorPosition //Cursor position .org 0x82B8FFC :: .incbin "data/m2-alphabet-table.bin" +.org 0x8002322 :: bl _2322_setup_windowing //Summary .org 0x80055B0 :: bl _4092_print_window //Printing diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index e4e42d2..3aef461 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -1635,4 +1635,15 @@ mov r10,r0 ldr r1,=#0x82B7FF8 pop {pc} -.pool \ No newline at end of file +.pool + +////============================================================================== +_2322_setup_windowing: //Fix the random garbage issue for the alphabet for good +push {lr} +bl 0x8012460 //Default code which sets up the names by copying memory which can be random +push {r0-r1} +ldr r0,=#m2_cstm_last_printed //Set the window flag to 0 so no issue can happen +mov r1,#0 +strb r1,[r0,#0] +pop {r0-r1} +pop {pc} \ No newline at end of file From 33648e04d1dd02eb5448e609127fa121aeedf3f8 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sun, 11 Aug 2019 00:55:47 +0200 Subject: [PATCH 4/8] Remove need of offset. --- src/c/vwf.c | 154 ++++++++++++------------ src/c/vwf.h | 5 +- src/data/m2-coord-table-file-select.bin | Bin 0 -> 896 bytes src/m2-hack.asm | 5 +- src/m2-vwf-entries.asm | 3 +- 5 files changed, 82 insertions(+), 85 deletions(-) create mode 100644 src/data/m2-coord-table-file-select.bin diff --git a/src/c/vwf.c b/src/c/vwf.c index faed979..df2c84f 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -22,9 +22,14 @@ int get_tile_number(int x, int y) { x--; y--; - if(y > 0xF) - y = 0xE + (y & 1); - return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32; //This is... Very not suited for tilemaps of variable width, which can have more than 0x10 tiles vertically. + return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32; +} + +int get_tile_number_file_select(int x, int y) +{ + x--; + y--; + return m2_coord_table_file[x + ((y >> 1) * 28)] + (y & 1) * 32; } int get_tile_number_with_offset(int x, int y) @@ -58,9 +63,8 @@ byte reduce_bit_depth(int row, int foreground) void clear_tile_file(int x, int y, int pixels, int tile_offset_file) { // Clear pixels - int tileIndex = get_tile_number(x, y) + tile_offset_file; - if(((tileIndex << 3) != (0xC9C0 >> 2)) && ((tileIndex << 3) != (0xC9E0 >> 2))) - cpufastset(&pixels, &vram[tileIndex * 8], CPUFASTSET_FILL | 8); + int tileIndex = get_tile_number_file_select(x, y) + tile_offset_file; + cpufastset(&pixels, &vram[tileIndex * 8], CPUFASTSET_FILL | 8); } // x,y: tile coordinates @@ -81,12 +85,12 @@ void clear_rect_file(int x, int y, int width, int height, int pixels, int tile_o void wrapper_file_string(int x, int y, int length, byte *str, int window_selector) { m2_cstm_last_printed[0] = window_selector; //First time setup - print_file_string(x, y, length, str, window_selector, 0); + print_file_string(x, y, length, str, window_selector, 1, 0); } void wrapper_delete_string(int x, int y, int length, byte *str, int window_selector) { - print_file_string(x, y, length, str - 0x20 + 0x40 - 0x15, window_selector, 0x6000); + print_file_string(x, y, length, str - 0x20 + 0x40 - 0x15, window_selector, 7, 0xA); } void wrapper_name_string(int x, int y, int length, byte *str, int window_selector) @@ -101,7 +105,7 @@ void wrapper_name_string(int x, int y, int length, byte *str, int window_selecto else String[i] = str[i]; } - print_file_string(x, y, length, String, window_selector, 0x7800); + print_file_string(x, y, length, String, window_selector, 5, 0); } void wrapper_name_summary_string(int x, int y, int length, byte *str, int window_selector) @@ -109,7 +113,12 @@ void wrapper_name_summary_string(int x, int y, int length, byte *str, int window char String[length]; for(int i = 0; i < length; i++) String[i] = str[i]; - print_file_string(x, y, length, String, window_selector, 0x2800); + print_file_string(x, y, length, String, window_selector, 3, 0); +} + +void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector) +{ + print_file_string(x, y, length, str, window_selector, 8, 0xC); } int count_pixels(byte *str, int length) @@ -124,11 +133,6 @@ int count_pixels(byte *str, int length) return tiles; } -void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector) -{ - print_file_string(x, y, length, str, window_selector, 0x6000); -} - void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr) { for(int i = x; i < width - 2; i++) @@ -143,18 +147,19 @@ void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr) } } -void print_file_string(int x, int y, int length, byte *str, int window_selector, int offset) +void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY) { int *tilesetBasePtr = (int *)(0x82B79B4 + (window_selector * 20)); int width = tilesetBasePtr[2]; unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]); - clearArr(x, y, width, tilesetDestPtr); //Cleans all of the arrangements this line could ever use + tilesetDestPtr = tilesetDestPtr - windowX - (windowY * width); + clearArr(x + windowX, y + windowY, width, tilesetDestPtr); //Cleans all of the arrangements this line could ever use - int pixelX = x * 8; - int pixelY = (y * 8) + 3; + int pixelX = (x + windowX) * 8; + int pixelY = ((y + windowY) * 8) + 3; int realmask = *palette_mask; *palette_mask = 0; //File select is special and changes its palette_mask on the fly. - clear_rect_file(x, y, width, 2, 0x11111111, 0x400 + (offset >> 5), tilesetDestPtr); //Clean the rectangle before printing + clear_rect_file(x + windowX, y + windowY, width, 2, 0x11111111, 0x400, tilesetDestPtr); //Clean the rectangle before printing for (int i = 0; i < length; i++) { @@ -188,11 +193,10 @@ void print_file_string(int x, int y, int length, byte *str, int window_selector, pixelY, 0, 9, - vram + 0x2000 + (offset >> 2), - &get_tile_number, + vram + 0x2000, + &get_tile_number_file_select, tilesetDestPtr, - width, - (offset >>5)); + width); pixelX += pixels; } @@ -445,7 +449,7 @@ void options_setup(char String[]) // Re-position format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = 64; + String[index++] = (0xC << 3); char Copy[] = "Copy"; for(int i = 0; i < (sizeof(Copy) -1); i++) @@ -453,7 +457,7 @@ void options_setup(char String[]) // Re-position format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = 97; + String[index++] = (0x10 << 3); char Delete[] = "Delete"; for(int i = 0; i < (sizeof(Delete) -1); i++) @@ -461,7 +465,7 @@ void options_setup(char String[]) // Re-position format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = 137; + String[index++] = (0x15 << 3); char Setup[] = "Set Up"; for(int i = 0; i < (sizeof(Setup) -1); i++) @@ -762,12 +766,12 @@ void summary_setup(char String[], int selector) String[index++] = encode_ascii(AreYouSure[i]); //Re-position format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x10) << 3; + String[index++] = (0x13) << 3; for(int i = 0; i < (sizeof(Yep) -1); i++) String[index++] = encode_ascii(Yep[i]); //Re-position format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x14) << 3; + String[index++] = (0x17) << 3; for(int i = 0; i < (sizeof(Nope) -1); i++) String[index++] = encode_ascii(Nope[i]); break; @@ -776,67 +780,61 @@ void summary_setup(char String[], int selector) String[index++] = 0xFF; } -void print_windows(int window_selector) +void print_windows(int windowX, int windowY, int window_selector) { char String[64]; - int offset = 0; switch(window_selector) { case 0x10: //Delete - offset = 0x6000; delete_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, offset); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); delete_setup(String, 1); - print_file_string(2, 5, 0x40, String, window_selector, offset); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); delete_setup(String, 2); - print_file_string(2, 7, 0x40, String, window_selector, offset); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); break; case 0xE: //Options - offset = 0x1800; options_setup(String); - print_file_string(2, 1, 0x40, String, window_selector, offset); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); break; case 1: //Text Speed if(((m2_cstm_last_printed[0] & 0x1F) != 2) && ((m2_cstm_last_printed[0] & 0x1F) != 1)) //If Text Flavour is printed, then this is too. No need to reprint. Avoids tearing { - offset = 0x6000; text_speed_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, offset); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); text_speed_setup(String, 1); - print_file_string(2, 3, 0x40, String, window_selector, offset); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); text_speed_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, offset); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); text_speed_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, offset); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); } break; case 0x2: //Text Flavour if((m2_cstm_last_printed[0] & 0x1F) != 2){ - offset = 0x2800; text_flavour_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, offset); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 1); - print_file_string(1, 3, 0x40, String, window_selector, offset); + print_file_string(1, 3, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, offset); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, offset); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 4); - print_file_string(2, 9, 0x40, String, window_selector, offset); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 5); - print_file_string(2, 11, 0x40, String, window_selector, offset); + print_file_string(2, 11, 0x40, String, window_selector, windowX, windowY); text_flavour_setup(String, 6); - print_file_string(2, 13, 0x40, String, window_selector, offset); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. } break; case 0xF: //Copy - offset = 0x6000; copy_setup(String); - print_file_string(1, 1, 0x40, String, window_selector, offset); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); break; case 0x3: //Ness' name + description case 0x4: //Paula's name + description @@ -846,9 +844,8 @@ void print_windows(int window_selector) case 0x8: //FavFood's name + description case 0x9: //FavThing's name + description if((m2_cstm_last_printed[0] & 0x1F) != window_selector){ - offset = 0x1800; description_setup(String, window_selector); - print_file_string(9, 1, 0x40, String, window_selector, offset); + print_file_string(9, 1, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); } break; @@ -856,19 +853,18 @@ void print_windows(int window_selector) if((m2_cstm_last_printed[0] & 0x20) == 0) //Print this once and stop { //Main thing - offset = 0x2800; alphabet_setup(String, 0, true); - print_file_string(2, 1, 0x40, String, window_selector, offset); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 1, true); - print_file_string(2, 3, 0x40, String, window_selector, offset); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 2, true); - print_file_string(2, 5, 0x40, String, window_selector, offset); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 3, true); - print_file_string(2, 7, 0x40, String, window_selector, offset); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, offset); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, offset); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x20; //Printed flag } break; @@ -876,19 +872,18 @@ void print_windows(int window_selector) if((m2_cstm_last_printed[0] & 0x40) == 0) //Print this once and stop { //Main thing - offset = 0x2800; alphabet_setup(String, 0, false); - print_file_string(2, 1, 0x40, String, window_selector, offset); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 1, false); - print_file_string(2, 3, 0x40, String, window_selector, offset); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 2, false); - print_file_string(2, 5, 0x40, String, window_selector, offset); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 3, false); - print_file_string(2, 7, 0x40, String, window_selector, offset); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, offset); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, offset); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x40; //Printed flag } @@ -897,13 +892,12 @@ void print_windows(int window_selector) break; case 0xD: //Is this okay? Yes No - offset = 0x2800; summary_setup(String, 0); - print_file_string(0xC, 5, 0x40, String, window_selector, offset); + print_file_string(0xC, 5, 0x40, String, window_selector, windowX, windowY); summary_setup(String, 1); - print_file_string(0xC, 0xB, 0x40, String, window_selector, offset); + print_file_string(0xC, 0xB, 0x40, String, window_selector, windowX, windowY); summary_setup(String, 2); - print_file_string(0x1, 0x11, 0x40, String, window_selector, offset); + print_file_string(0x1, 0x11, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. break; default: //File select string, already printed @@ -1018,7 +1012,7 @@ void format_file_string(FILE_SELECT *file) // Re-position format_file_cc(file, &index, CUSTOMCC_SET_X); - file->formatted_str[index++] = 72; + file->formatted_str[index++] = (0x10 << 3); for (int i = 0; i < (sizeof(levelStr) - 1); i++) file->formatted_str[index++] = encode_ascii(levelStr[i]); @@ -1052,12 +1046,12 @@ byte print_character_formatted(byte chr, int x, int y, int font, int foreground) return 8; } - return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, *tilemap_pointer, 32, 0); + return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, *tilemap_pointer, 32); } byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground) { - return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, NULL, 32, 0); + return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, NULL, 32); } // Prints a special tile. Pixels are copied to the VWF buffer. @@ -1095,7 +1089,7 @@ 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 tilemapOffset) + int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth) { int tileWidth = m2_font_widths[font]; int tileHeight = m2_font_heights[font]; @@ -1147,9 +1141,9 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro if (tilemapPtr != NULL) { - tilemapPtr[tileX + dTileX + ((tileY + dTileY) * tilemapWidth)] = paletteMask | (tileIndex + tilemapOffset); + tilemapPtr[tileX + dTileX + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex; if(useful) - tilemapPtr[tileX + dTileX + ((tileY + dTileY + 1) * tilemapWidth)] = paletteMask | (realTileIndex + tilemapOffset); + tilemapPtr[tileX + dTileX + ((tileY + dTileY + 1) * tilemapWidth)] = paletteMask | realTileIndex; } if (renderedWidth - leftPortionWidth > 0 && leftPortionWidth < 8) @@ -1182,9 +1176,9 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro if (tilemapPtr != NULL) { - tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY) * tilemapWidth)] = paletteMask | (tileIndex + tilemapOffset); + tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex ; if(useful) - tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY + 1) * tilemapWidth)] = paletteMask | (realTileIndex + tilemapOffset); + tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY + 1) * tilemapWidth)] = paletteMask | realTileIndex; } } diff --git a/src/c/vwf.h b/src/c/vwf.h index 4e28bed..b4af825 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -38,7 +38,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 tilemapOffset); + int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth); 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); @@ -68,11 +68,12 @@ void print_number_menu_current(byte digit, WINDOW* window); void clear_number_menu(WINDOW* window); void format_cash_window(int value, int padding, byte* str); void handle_first_window(WINDOW* window); -void print_file_string(int x, int y, int length, byte *str, int window_selector, int offset); +void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY); void wrapper_file_string(int x, int y, int length, byte *str, int window_selector); void format_file_string(FILE_SELECT *file); extern unsigned short m2_coord_table[]; +extern unsigned short m2_coord_table_file[]; extern int m2_bits_to_nybbles[]; extern byte m2_nybbles_to_bits[]; extern byte *m2_font_table[]; diff --git a/src/data/m2-coord-table-file-select.bin b/src/data/m2-coord-table-file-select.bin new file mode 100644 index 0000000000000000000000000000000000000000..0daa8b15169fd2dfa3efb7e1939acf9592e777ce GIT binary patch literal 896 zcmWO4141MK00q#GY#UdZY@2hHYO-xyCEMn9mF*1g0fbVCgIL5N9tlW9 z5|WXERHPvt8OTHyvXO&a%AF@0+j#{w3yj{_Xy2*)_VDb8?? z3tZv~*SNtg?r@I>JmLw@c)=^)@Qx3B;tSvS!9V;0BtCRH-Uet46h| zQ=^*HtQNJZP3`JXr@GXw9`&kE{R(P8gBnsu!y3`3#x$-8O=?Qhn$fK0G_M6MYDvpl z(W=(8t_^K!OWWGfuJ*LA10Cu}$2!re&UCH|UFu5Ly3wufbgu_J>PgRf(W~C{t`B|c zOW*p@KmGotre!mqa5uR$2!jOPH>`=oa_{*I?d_MaHg}I?HuPi&-pHJp#v^* zu}fU)GMBr;m9BENYh3F(*So=uZgR6*-0C*ByThICa<_Zj>pu58=m8IU$RQ7V#G@Yb TxF Date: Sun, 11 Aug 2019 01:30:23 +0200 Subject: [PATCH 5/8] Make sure arrangements are properly cleared. --- src/c/vwf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/c/vwf.c b/src/c/vwf.c index df2c84f..7161388 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -133,9 +133,9 @@ int count_pixels(byte *str, int length) return tiles; } -void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr) +void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr, int windowX) { - for(int i = x; i < width - 2; i++) + for(int i = x; i < width + windowX - 2; i++) { if((tilesetDestPtr[i + (y * width)] & 0x3FF) != 0x95) { @@ -153,7 +153,7 @@ void print_file_string(int x, int y, int length, byte *str, int window_selector, int width = tilesetBasePtr[2]; unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]); tilesetDestPtr = tilesetDestPtr - windowX - (windowY * width); - clearArr(x + windowX, y + windowY, width, tilesetDestPtr); //Cleans all of the arrangements this line could ever use + clearArr(x + windowX, y + windowY, width, tilesetDestPtr, windowX); //Cleans all of the arrangements this line could ever use int pixelX = (x + windowX) * 8; int pixelY = ((y + windowY) * 8) + 3; From cf3eb45ef9b0258b9689867e08bfa3a9028ad681 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sun, 11 Aug 2019 05:20:42 +0200 Subject: [PATCH 6/8] Remove issues with background windows introduced after the offset removal --- src/c/vwf.c | 2 +- src/m2-hack.asm | 2 + src/m2-vwf-entries.asm | 96 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/c/vwf.c b/src/c/vwf.c index 7161388..9fa7a3b 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -800,7 +800,7 @@ void print_windows(int windowX, int windowY, int window_selector) m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); break; case 1: //Text Speed - if(((m2_cstm_last_printed[0] & 0x1F) != 2) && ((m2_cstm_last_printed[0] & 0x1F) != 1)) //If Text Flavour is printed, then this is too. No need to reprint. Avoids tearing + if((m2_cstm_last_printed[0] & 0x1F) != 1) //If Text Flavour is printed, don't reprint it { text_speed_setup(String, 0); print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 411c75b..b123584 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1095,6 +1095,7 @@ nop .org 0x80053F2 :: mov r1,#4 .org 0x82B79E4 :: dw 0xF //new window width .org 0x82B79E8 :: dw 0x10 //new window height +.org 0x8003DCE :: bl _3dce_fix_out_of_text_flavour .org 0x86DB1F8 :: .incbin "data/m2-flavour-template.bin" //Delete @@ -1109,6 +1110,7 @@ nop .org 0x8004268 :: mov r2,#0x2 :: bl wrapper_copy_string //Descriptions and Names +.org 0x80053F6 :: bl _53f6_fix_out_of_description .org 0x8004ED2 :: bl wrapper_name_string //Printing names .org 0x8004EDC :: bl _4092_print_window //Printing descriptions .org 0x86DB2B8 :: .incbin "data/m2-descriptions-template.bin" diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index 1e4a759..c723af2 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -1636,13 +1636,89 @@ pop {pc} .pool -////============================================================================== -_2322_setup_windowing: //Fix the random garbage issue for the alphabet for good -push {lr} -bl 0x8012460 //Default code which sets up the names by copying memory which can be random -push {r0-r1} -ldr r0,=#m2_cstm_last_printed //Set the window flag to 0 so no issue can happen -mov r1,#0 -strb r1,[r0,#0] -pop {r0-r1} -pop {pc} \ No newline at end of file +//============================================================================== +//Fix the random garbage issue for the alphabet for good +_2322_setup_windowing: +push {lr} +bl 0x8012460 //Default code which sets up the names by copying memory which can be random +push {r0-r1} +ldr r0,=#m2_cstm_last_printed //Set the window flag to 0 so no issue can happen +mov r1,#0 +strb r1,[r0,#0] +pop {r0-r1} +pop {pc} + +.pool + +//============================================================================== +//Loads and prints the text lines for the file select main window +_setup_file_strings: +push {r4-r5,lr} +add sp,#-4 +ldr r5,=#0x3000024 +ldr r2,[r5,#0] +mov r4,#0 +str r4,[r2,#4] +mov r0,#0 +bl 0x8002170 //Routine which loads the save corresponding to r0 +mov r0,#1 +bl 0x8002170 +mov r0,#2 +bl 0x8002170 +ldr r3,[r5,#0] +mov r0,#0x84 +lsl r0,r0,#2 +add r3,r3,r0 +str r4,[sp,#0] +mov r0,#2 +mov r1,#1 +mov r2,#0x40 +bl wrapper_file_string +ldr r3,[r5,#0] +ldr r0,=#0x454 +add r3,r3,r0 +str r4,[sp,#0] +mov r0,#2 +mov r1,#3 +mov r2,#0x40 +bl wrapper_file_string +ldr r3,[r5,#0] +mov r0,#0xD3 +lsl r0,r0,#3 +add r3,r3,r0 +str r4,[sp,#0] +mov r0,#2 +mov r1,#5 +mov r2,#0x40 +bl wrapper_file_string +add sp,#4 +pop {r4-r5,pc} + +.pool + +//============================================================================== +// +_53f6_fix_out_of_description: +push {lr} +bl 0x800341C +bl _setup_file_strings +pop {pc} + +//============================================================================== +// +_3dce_fix_out_of_text_flavour: +push {lr} +bl 0x8003F44 +mov r0,#0 +ldsh r0,[r5,r0] //Checks whether or not to print the option menu +cmp r0,#0 +blt @@end + +mov r0,#4 +mov r1,#7 +mov r2,#0xE +bl _4092_print_window //Prints the option menu + +@@end: +bl _setup_file_strings +pop {pc} \ No newline at end of file From 2ab18de102736800dbae37ae04fcaa2b602588bf Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sun, 11 Aug 2019 23:49:45 +0200 Subject: [PATCH 7/8] Fix issue with text speed window printing when pressing up or down in the text flavour window. --- src/c/vwf.c | 4 +++- src/m2-hack.asm | 2 ++ src/m2-vwf-entries.asm | 22 +++++++++++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/c/vwf.c b/src/c/vwf.c index 9fa7a3b..acb92d6 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -800,7 +800,7 @@ void print_windows(int windowX, int windowY, int window_selector) m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); break; case 1: //Text Speed - if((m2_cstm_last_printed[0] & 0x1F) != 1) //If Text Flavour is printed, don't reprint it + if(((m2_cstm_last_printed[0] & 0x1F) != 1) && ((m2_cstm_last_printed[0] & 0x80) == 0)) //If Text Flavour is printed, don't reprint it { text_speed_setup(String, 0); print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); @@ -812,6 +812,8 @@ void print_windows(int windowX, int windowY, int window_selector) print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); } + else if ((m2_cstm_last_printed[0] & 0x80) != 0) //This has not been printed. Instead Text Flavour has been. + m2_cstm_last_printed[0] = 2; break; case 0x2: //Text Flavour if((m2_cstm_last_printed[0] & 0x1F) != 2){ diff --git a/src/m2-hack.asm b/src/m2-hack.asm index b123584..98e6c1a 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1082,6 +1082,8 @@ nop //Text Speed options .org 0x8003BBC :: bl _4092_print_window //Printing .org 0x8003FA2 :: bl _4092_print_window +.org 0x8003E86 :: bl _3e86_special_setup //Avoid printing when not necessary +.org 0x8003EF2 :: bl _3e86_special_setup //Avoid printing when not necessary .org 0x82B79D0 :: dw 0x10 //new window width .org 0x86DB0FC :: .incbin "data/m2-textspeed-template.bin" diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index c723af2..f953859 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -1603,6 +1603,7 @@ mov r3,#0 pop {pc} //============================================================================== +//X cursor for the Options submenu in the File Select window _41D4_cursor_X: push {lr} cmp r0,#1 @@ -1627,6 +1628,7 @@ lsl r0,r0,#3 pop {pc} //============================================================================== +//Makes sure Paula's window is loaded properly since the name length has been changed to 5 and the game previously used the 4 to load the window too _4f7c_window_selector: push {lr} mov r0,#4 @@ -1697,7 +1699,7 @@ pop {r4-r5,pc} .pool //============================================================================== -// +//Fixes issue with file select menu not printing after going back to it from the alphabet _53f6_fix_out_of_description: push {lr} bl 0x800341C @@ -1705,7 +1707,7 @@ bl _setup_file_strings pop {pc} //============================================================================== -// +//Fixes issue with the option submenu (if it's there) and the file select menu after going back to the text speed window from the text flavour window _3dce_fix_out_of_text_flavour: push {lr} bl 0x8003F44 @@ -1721,4 +1723,18 @@ bl _4092_print_window //Prints the option menu @@end: bl _setup_file_strings -pop {pc} \ No newline at end of file +pop {pc} + +//============================================================================== +//Fixes text reprinting when pressing up or down in the text flavour window +_3e86_special_setup: +push {lr} +push {r0-r2} +ldr r0,=#m2_cstm_last_printed +ldrb r2,[r0,#0] +mov r1,#0x80 +orr r1,r2 +strb r1,[r0,#0] +pop {r0-r2} +bl 0x8003F44 +pop {pc} \ No newline at end of file From 743c7396f5befb822ef9d83321d0e2c0a59f6e97 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Mon, 12 Aug 2019 23:39:49 +0200 Subject: [PATCH 8/8] Add highlighting - Fix issue with file arrangement not being properly updated - Move everrything related to the file selection menu to fileselect.c Also put 4 more pixels between Ness' name in the file select main window and Level. --- build.ps1 | 3 +- src/c/fileselect.c | 1023 ++++++++++++++++++++++++++++++++++++++++ src/c/fileselect.h | 43 ++ src/c/vwf.c | 994 ++------------------------------------ src/c/vwf.h | 9 +- src/m2-hack.asm | 20 +- src/m2-vwf-entries.asm | 80 +++- 7 files changed, 1186 insertions(+), 986 deletions(-) create mode 100644 src/c/fileselect.c diff --git a/build.ps1 b/build.ps1 index 799f87d..5132d0a 100644 --- a/build.ps1 +++ b/build.ps1 @@ -14,7 +14,8 @@ $input_c_files = "src/c/ext.c", "src/c/vwf.c", "src/c/locs.c", - "src/c/goods.c" + "src/c/goods.c", + "src/c/fileselect.c" $base_c_address = 0x8100000; $scripttool_cmd = "bin/ScriptTool/ScriptTool.dll" diff --git a/src/c/fileselect.c b/src/c/fileselect.c new file mode 100644 index 0000000..9ce9d9a --- /dev/null +++ b/src/c/fileselect.c @@ -0,0 +1,1023 @@ +#include "window.h" +#include "vwf.h" +#include "number-selector.h" +#include "locs.h" +#include "fileselect.h" + +int get_tile_number_file_select(int x, int y) +{ + x--; + y--; + return m2_coord_table_file[x + ((y >> 1) * 28)] + (y & 1) * 32; +} + +// x,y: tile coordinates +void clear_tile_file(int x, int y, int pixels, int tile_offset_file) +{ + // Clear pixels + int tileIndex = get_tile_number_file_select(x, y) + tile_offset_file; + cpufastset(&pixels, &vram[tileIndex * 8], CPUFASTSET_FILL | 8); +} + +// x,y: tile coordinates +void clear_rect_file(int x, int y, int width, int height, int pixels, int tile_offset_file, unsigned short *tilesetDestPtr) +{ + for (int tileY = 0; tileY < height; tileY++) + { + for (int tileX = 0; tileX < width; tileX++) + { + if((tilesetDestPtr[x + tileX + ((y + tileY) * width)] & 0x3FF) != 0x95) + clear_tile_file(x + tileX, y + tileY, pixels, tile_offset_file); + else + break; + } + } +} + +unsigned short* getTilesetDest(int window_selector, int *width) +{ + int *tilesetBasePtr = (int *)(0x82B79B4 + (window_selector * 20)); + (*width) = tilesetBasePtr[2]; + return (unsigned short *)(tilesetBasePtr[0]); +} +unsigned short getPaletteFromFileWindow(int x, int y, int window_selector) +{ + int width; + unsigned short *tilesetDestPtr = getTilesetDest(window_selector, &width); + return (tilesetDestPtr[x + (y * width)] & 0x3000); //Get the palette used. Useful to keep the highlighting. +} + +void setPaletteToFileWindow(int x, int y, int window_selector, unsigned short palette) +{ + int width; + unsigned short *tilesetDestPtr = getTilesetDest(window_selector, &width); + tilesetDestPtr[x + (y * width)] = ((tilesetDestPtr[x + (y * width)] & 0x3FF) | palette); //Set the palette used. Useful to keep the highlighting. +} + +void setPaletteToZero(int x, int y, int window_selector) +{ + int width; + unsigned short *tilesetDestPtr = getTilesetDest(window_selector, &width); + tilesetDestPtr[x + (y * width)] = 0x013F; //Set palette to 0 when this one is called. No highlighting here. +} + +void setPaletteOnAllFile(int x, int y, byte *str, int length, int window_selector) +{ + int width; + unsigned short *tilesetDestPtr = getTilesetDest(window_selector, &width); + unsigned short palette = getPaletteFromFileWindow(x, y, window_selector); + for(int i = 0; i < count_pixels_to_tiles(str, length, (x + 1) << 3); i++) + { + tilesetDestPtr[i + x + (y * width)] = (tilesetDestPtr[i + x + (y * width)] & 0x3FF) | palette; + tilesetDestPtr[i + x + ((y + 1) * width)] = (tilesetDestPtr[i + x + ((y + 1) * width)] & 0x3FF) | palette; + } +} + +void wrapper_file_string_selection(int x, int y, int length, byte *str, int window_selector) +{ + m2_cstm_last_printed[0] = window_selector; //First time setup + print_file_string(x, y, length, str, window_selector, 1, 0); + setPaletteOnAllFile(x, y, str, length, window_selector); +} + +void setPaletteOnFile(int x, int y, int window_selector, FILE_SELECT *file) +{ + setPaletteOnAllFile(x, y, file->formatted_str, 0x40, window_selector); +} + +void wrapper_first_file_string(int x, int y, int length, byte *str, int window_selector) +{ + setPaletteToZero(x, y, window_selector); //The game does not reset the palette for these lines. Instead it reprints them with palette 0. Hence if we want to mantain the highlighting consistent, we need to set the palette our code will use to 0 ourselves. + m2_cstm_last_printed[0] = window_selector; //First time setup + print_file_string(x, y, length, str, window_selector, 1, 0); +} + +void wrapper_delete_string(int x, int y, int length, byte *str, int window_selector) +{ + print_file_string(x, y, length, str - 0x20 + 0x40 - 0x15, window_selector, 7, 0xA); +} + +void wrapper_name_string(int x, int y, int length, byte *str, int window_selector) +{ + char String[length]; + for(int i = 0; i < length; i++) + { + if(str[i] == 0xFD) + String[i] = 0x70; + else if(str[i] == 0xF1) + String[i] = 0x53; + else + String[i] = str[i]; + } + print_file_string(x, y, length, String, window_selector, 5, 0); +} + +void wrapper_name_summary_string(int x, int y, int length, byte *str, int window_selector) +{ + char String[length]; + for(int i = 0; i < length; i++) + String[i] = str[i]; + print_file_string(x, y, length, String, window_selector, 3, 0); +} + +void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector) +{ + print_file_string(x, y, length, str, window_selector, 8, 0xC); +} + +void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr, int windowX) +{ + for(int i = x; i < width + windowX - 2; i++) + { + if((tilesetDestPtr[i + (y * width)] & 0x3FF) != 0x95) + { + tilesetDestPtr[i + (y * width)] = 0x13F; + tilesetDestPtr[i + ((y+1) * width)] = 0x13F; + } + else + break; + } +} + +void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY) +{ + int *tilesetBasePtr = (int *)(0x82B79B4 + (window_selector * 20)); + int width = tilesetBasePtr[2]; + unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]); + unsigned short getBasePal = tilesetDestPtr[x + (y * width)] & 0x3000; + tilesetDestPtr = tilesetDestPtr - windowX - (windowY * width); + clearArr(x + windowX, y + windowY, width, tilesetDestPtr, windowX); //Cleans all of the arrangements this line could ever use + + int pixelX = (x + windowX) * 8; + int pixelY = ((y + windowY) * 8) + 3; + int realmask = *palette_mask; + *palette_mask = getBasePal; //File select is special and changes its palette_mask on the fly. + clear_rect_file(x + windowX, y + windowY, width, 2, 0x11111111, 0x400, tilesetDestPtr); //Clean the rectangle before printing + + for (int i = 0; i < length; i++) + { + byte chr = str[i]; + + if (chr == 0xFF) + { + break; // the game does something else here, haven't looked into what exactly + } + else if (chr == 0xFE) + { + // Define 0xFE as a control code + byte cmd = str[++i]; + switch (cmd) + { + case CUSTOMCC_ADD_X: + pixelX += str[++i]; + break; + + case CUSTOMCC_SET_X: + pixelX = str[++i]; + break; + } + continue; + } + + chr = decode_character(chr); + int pixels = print_character_with_callback( + chr, + pixelX, + pixelY, + 0, + 9, + vram + 0x2000, + &get_tile_number_file_select, + tilesetDestPtr, + width); + + pixelX += pixels; + } + *palette_mask = realmask; +} + +unsigned short setupCursorAction(int *Pos1, int *Pos2) +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + int alphabet = caller[0xDAC >> 2]; + int *table = (int *)0x82B8FFC; //Address of the alphabet table + + int choice = 0; + int counter = 0; + + for(int i = 0; i < CursorY; i++) + { + if(i <= 4) + choice += 0xE; + else + choice += 3; + } + + choice += CursorX; + (*Pos1) = alphabet; + (*Pos2) = choice; + + unsigned short letter = (table[choice] >> (16 * alphabet)); + return letter; +} + +void setupCursorMovement() +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + int yAxys = 0; + int xAxys = 0; + + // Check for pressing left or right + PAD_STATE state = *pad_state; + + if (state.right) + xAxys = 1; + else if (state.left) + xAxys = -1; + else if (state.up) + yAxys = -1; + else if(state.down) + yAxys = 1; + + if(xAxys != 0) + { + CursorX += xAxys; + switch(CursorY) + { + case 0: + case 1: + case 2: + if(CursorX < 0) + CursorX = 0xA; + if(CursorX > 0xA) + CursorX = 0; + break; + case 3: + if(CursorX < 0) + CursorX = 0xB; + if(CursorX > 0xB) + CursorX = 0; + break; + case 4: + if(CursorX < 0) + CursorX = 0x3; + if(CursorX > 0x3) + CursorX = 0; + break; + default: + if(CursorX < 0) + CursorX = 0x2; + if(CursorX > 0x2) + CursorX = 0; + break; + } + m2_soundeffect(0x1A7); + } + else if(yAxys != 0) + { + switch(CursorY) + { + case 0: + case 1: + case 2: + CursorY += yAxys; + if(CursorY < 0) + { + if((CursorX >= 0x9)) + { + CursorX = 2 + CursorX - 0x9; + CursorY = 4; + } + else if(CursorX == 0) + CursorY = 5; + else + CursorY = 3; + } + else if(CursorY == 3 && CursorX >= 0x9) + CursorX += 1; + break; + case 3: + CursorY += yAxys; + if(CursorY == 2 && CursorX >= 9) + CursorX -=1; + if(CursorY == 4) + { + if(CursorX <= 3) + CursorX = 0; + else if (CursorX <= 9) + CursorX = 1; + else + CursorX = 2 + CursorX - 0xA; + } + break; + case 4: + CursorY += yAxys; + if(CursorY == 3) + { + if(CursorX >= 2) + CursorX = 0xA + CursorX - 2; + if(CursorX == 1) + CursorX = 4; + } + if(CursorY == 5) + { + if(CursorX >= 2) + CursorX = 1; + else + CursorX = 0; + } + break; + default: + CursorY += yAxys; + if(CursorY == 4 && CursorX == 2) + CursorX = 3; + if(CursorY == 6) + { + if(CursorX == 0) + CursorY = 0; + else + CursorY = 5; + } + break; + } + m2_soundeffect(0x1A8); + } + + caller[0xDA4 >> 2] = CursorX; + caller[0xDA8 >> 2] = CursorY; +} + +void setupCursorPosition(int *x, int *y) +{ + int *a = (int *)0x3000024; + int *caller = (int *)a[0]; + int CursorX = caller[0xDA4 >> 2]; + int CursorY = caller[0xDA8 >> 2]; + (*x) = 0; + (*y) = 0; + if(CursorY <= 4) + { + (*y) = 2 + (CursorY << 1); + switch(CursorY) + { + case 0: + case 1: + case 2: + switch(CursorX) + { + case 9: + case 0xA: + (*x) = 23 + ((CursorX -9) << 1); + break; + default: + (*x) = 1 + (CursorX << 1); + break; + } + break; + case 3: + switch(CursorX) + { + case 0xA: + case 0xB: + (*x) = 23 + ((CursorX -0xA) << 1); + break; + default: + (*x) = 1 + (CursorX << 1); + break; + } + break; + default: + switch(CursorX) + { + case 0: + (*x) = 1; + break; + case 1: + (*x) = 8; + break; + case 2: + case 3: + (*x) = 23 + ((CursorX- 2) << 1); + break; + } + break; + } + } + else + { + (*y) = 14; + switch(CursorX) + { + case 0: + (*x) = 1; + break; + case 1: + (*x) = 18; + break; + default: + (*x) = 26; + break; + } + } +} + +void format_options_cc(char String[], int *index, byte cmd) +{ + String[(*index)++] = 0xFE; + String[(*index)++] = cmd; +} + +void options_setup(char String[], int selector) +{ + int index = 0; + char Continue[] = "Continue"; + char Copy[] = "Copy"; + char Delete[] = "Delete"; + char Setup[] = "Set Up"; + switch(selector) + { + case 0: + for(int i = 0; i < (sizeof(Continue) -1); i++) + String[index++] = encode_ascii(Continue[i]); + break; + case 1: + for(int i = 0; i < (sizeof(Copy) -1); i++) + String[index++] = encode_ascii(Copy[i]); + break; + case 2: + for(int i = 0; i < (sizeof(Delete) -1); i++) + String[index++] = encode_ascii(Delete[i]); + break; + default: + for(int i = 0; i < (sizeof(Setup) -1); i++) + String[index++] = encode_ascii(Setup[i]); + break; + } + + //END + String[index++] = 0xFF; +} + +void text_speed_setup(char String[], int selector) +{ + int index = 0; + char Text_Speed[] = "Please select text speed."; + char Medium[] = "Medium"; + char Fast[] = "Fast"; + char Slow[] = "Slow"; + switch(selector) + { + case 0: + for(int i = 0; i < (sizeof(Text_Speed) -1); i++) + String[index++] = encode_ascii(Text_Speed[i]); + break; + case 1: + for(int i = 0; i < (sizeof(Fast) -1); i++) + String[index++] = encode_ascii(Fast[i]); + break; + case 2: + for(int i = 0; i < (sizeof(Medium) -1); i++) + String[index++] = encode_ascii(Medium[i]); + break; + default: + for(int i = 0; i < (sizeof(Slow) -1); i++) + String[index++] = encode_ascii(Slow[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void delete_setup(char String[], int selector) +{ + int index = 0; + char Delete[] = "Are you sure you want to delete?"; + char No[] = "No"; + char Yes[] = "Yes"; + switch(selector) + { + case 0: + for(int i = 0; i < (sizeof(Delete) -1); i++) + String[index++] = encode_ascii(Delete[i]); + break; + case 1: + for(int i = 0; i < (sizeof(No) -1); i++) + String[index++] = encode_ascii(No[i]); + break; + default: + for(int i = 0; i < (sizeof(Yes) -1); i++) + String[index++] = encode_ascii(Yes[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void text_flavour_setup(char String[], int selector) +{ + int index = 0; + char Text_Flavour_1[] = "Which style of windows"; + char Text_Flavour_2[] = "do you prefer?"; + char Plain[] = "Plain flavor"; + char Mint[] = "Mint flavor"; + char Strawberry[] = "Strawberry flavor"; + char Banana[] = "Banana flavor"; + char Peanut[] = "Peanut flavor"; + switch(selector) + { + case 0: + for(int i = 0; i < (sizeof(Text_Flavour_1) -1); i++) + String[index++] = encode_ascii(Text_Flavour_1[i]); + break; + case 1: + for(int i = 0; i < (sizeof(Text_Flavour_2) -1); i++) + String[index++] = encode_ascii(Text_Flavour_2[i]); + break; + case 2: + for(int i = 0; i < (sizeof(Plain) -1); i++) + String[index++] = encode_ascii(Plain[i]); + break; + case 3: + for(int i = 0; i < (sizeof(Mint) -1); i++) + String[index++] = encode_ascii(Mint[i]); + break; + case 4: + for(int i = 0; i < (sizeof(Strawberry) -1); i++) + String[index++] = encode_ascii(Strawberry[i]); + break; + case 5: + for(int i = 0; i < (sizeof(Banana) -1); i++) + String[index++] = encode_ascii(Banana[i]); + break; + default: + for(int i = 0; i < (sizeof(Peanut) -1); i++) + String[index++] = encode_ascii(Peanut[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void description_setup(char String[], int selector) +{ + int index = 0; + char Ness[] = "Please name him."; + char Paula[] = "Name her, too."; + char Jeff[] = "Name your friend."; + char Poo[] = "Name another friend."; + char King[] = "Name your pet."; + char FavFood[] = "Favorite homemade food?"; + char FavThing[] = "What's your favorite thing?"; + switch(selector) + { + case 3: + for(int i = 0; i < (sizeof(Ness) -1); i++) + String[index++] = encode_ascii(Ness[i]); + break; + case 4: + for(int i = 0; i < (sizeof(Paula) -1); i++) + String[index++] = encode_ascii(Paula[i]); + break; + case 5: + for(int i = 0; i < (sizeof(Jeff) -1); i++) + String[index++] = encode_ascii(Jeff[i]); + break; + case 6: + for(int i = 0; i < (sizeof(Poo) -1); i++) + String[index++] = encode_ascii(Poo[i]); + break; + case 7: + for(int i = 0; i < (sizeof(King) -1); i++) + String[index++] = encode_ascii(King[i]); + break; + case 8: + for(int i = 0; i < (sizeof(FavFood) -1); i++) + String[index++] = encode_ascii(FavFood[i]); + break; + default: + for(int i = 0; i < (sizeof(FavThing) -1); i++) + String[index++] = encode_ascii(FavThing[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void copy_setup(char String[]) +{ + int index = 0; + char Copy[] = "Copy to where?"; + for(int i = 0; i < (sizeof(Copy) -1); i++) + String[index++] = encode_ascii(Copy[i]); + //END + String[index++] = 0xFF; +} + +void letterSetup(char String[], int selector, bool capital, int *index) +{ + char base = capital ? 'A' : 'a'; + int value = 9 - (selector >> 1); + for(int i = 0; i < value; i++) + { + String[(*index)++] = encode_ascii(base + i + (selector * 9)); + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + if(i != value -1) + String[(*index)++] = (2 * (i + 2)) << 3; + else + String[(*index)++] = (24) << 3; + } + switch(selector) + { + case 0: + String[(*index)++] = 93; + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + String[(*index)++] = (26) << 3; + String[(*index)++] = 83; + break; + case 1: + String[(*index)++] = 87; + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + String[(*index)++] = (26) << 3; + String[(*index)++] = 174; + break; + default: + String[(*index)++] = 94; + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + String[(*index)++] = (26) << 3; + String[(*index)++] = 95; + break; + } +} + +void numbersSetup(char String[], int *index) +{ + char base = '0'; + for(int i = 0; i < 10; i++) + { + String[(*index)++] = encode_ascii(base + i); + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + if(i != 9) + String[(*index)++] = (2 * (i + 2)) << 3; + else + String[(*index)++] = (24) << 3; + } + String[(*index)++] = 81; + // Re-position + format_options_cc(String, &(*index), CUSTOMCC_SET_X); + String[(*index)++] = (26) << 3; + String[(*index)++] = 0xAC; +} + +void alphabet_setup(char String[], int selector, bool capital) +{ + int index = 0; + char Capital[] = "CAPITAL"; + char Small[] = "small"; + char DontCare[] = "Don't Care"; + char Backspace[] = "Backspace"; + char Ok[] = "OK"; + switch(selector) + { + case 0: + case 1: + case 2: + letterSetup(String, selector, capital, &index); + break; + case 3: + numbersSetup(String, &index); + break; + case 4: + for(int i = 0; i < (sizeof(Capital) -1); i++) + String[index++] = encode_ascii(Capital[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (9) << 3; + for(int i = 0; i < (sizeof(Small) -1); i++) + String[index++] = encode_ascii(Small[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (24) << 3; + String[index++] = 111; + // Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (26) << 3; + String[index++] = 0xAF; + break; + default: + for(int i = 0; i < (sizeof(DontCare) -1); i++) + String[index++] = encode_ascii(DontCare[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (19) << 3; + for(int i = 0; i < (sizeof(Backspace) -1); i++) + String[index++] = encode_ascii(Backspace[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (27) << 3; + for(int i = 0; i < (sizeof(Ok) -1); i++) + String[index++] = encode_ascii(Ok[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void summary_setup(char String[], int selector) +{ + int index = 0; + char FavFood[] = "Favorite food:"; + char FavThing[] = "Coolest thing:"; + char AreYouSure[] = "Are you sure?"; + char Yep[] = "Yep"; + char Nope[] = "Nope"; + switch(selector) + { + case 0: + for(int i = 0; i < (sizeof(FavFood) -1); i++) + String[index++] = encode_ascii(FavFood[i]); + break; + case 1: + for(int i = 0; i < (sizeof(FavThing) -1); i++) + String[index++] = encode_ascii(FavThing[i]); + break; + default: + for(int i = 0; i < (sizeof(AreYouSure) -1); i++) + String[index++] = encode_ascii(AreYouSure[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (0x13) << 3; + for(int i = 0; i < (sizeof(Yep) -1); i++) + String[index++] = encode_ascii(Yep[i]); + //Re-position + format_options_cc(String, &index, CUSTOMCC_SET_X); + String[index++] = (0x17) << 3; + for(int i = 0; i < (sizeof(Nope) -1); i++) + String[index++] = encode_ascii(Nope[i]); + break; + } + //END + String[index++] = 0xFF; +} + +void print_windows(int windowX, int windowY, int window_selector) +{ + char String[64]; + unsigned short palettes[3]; + switch(window_selector) + { + case 0x10: //Delete + delete_setup(String, 0); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); + delete_setup(String, 1); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); + delete_setup(String, 2); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); + break; + case 0xE: //Options + palettes[0] = getPaletteFromFileWindow(0x8, 1, window_selector); + palettes[1] = getPaletteFromFileWindow(0xC, 1, window_selector); + palettes[2] = getPaletteFromFileWindow(0x11, 1, window_selector); + options_setup(String, 0); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); + options_setup(String, 1); + setPaletteToFileWindow(0x8, 1, window_selector, palettes[0]); //Makes sure the highlighting is kept + print_file_string(0x8, 1, 0x40, String, window_selector, windowX, windowY); + options_setup(String, 2); + setPaletteToFileWindow(0xC, 1, window_selector, palettes[1]); + print_file_string(0xC, 1, 0x40, String, window_selector, windowX, windowY); + options_setup(String, 3); + setPaletteToFileWindow(0x11, 1, window_selector, palettes[2]); + print_file_string(0x11, 1, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); + break; + case 1: //Text Speed + if(((m2_cstm_last_printed[0] & 0x1F) != 1) && ((m2_cstm_last_printed[0] & 0x80) == 0)) //If Text Flavour is printed, don't reprint it + { + text_speed_setup(String, 0); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); + text_speed_setup(String, 1); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); + text_speed_setup(String, 2); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); + text_speed_setup(String, 3); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); + } + else if ((m2_cstm_last_printed[0] & 0x80) != 0) //This has not been printed. Instead Text Flavour has been. + m2_cstm_last_printed[0] = 2; + break; + case 0x2: //Text Flavour + if((m2_cstm_last_printed[0] & 0x1F) != 2){ + text_flavour_setup(String, 0); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 1); + print_file_string(1, 3, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 2); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 3); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 4); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 5); + print_file_string(2, 11, 0x40, String, window_selector, windowX, windowY); + text_flavour_setup(String, 6); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. + } + break; + case 0xF: //Copy + copy_setup(String); + print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); + break; + case 0x3: //Ness' name + description + case 0x4: //Paula's name + description + case 0x5: //Jeff's name + description + case 0x6: //Poo's name + description + case 0x7: //King's name + description + case 0x8: //FavFood's name + description + case 0x9: //FavThing's name + description + if((m2_cstm_last_printed[0] & 0x1F) != window_selector){ + description_setup(String, window_selector); + print_file_string(9, 1, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); + } + break; + case 0xA: //Alphabet 1 + if((m2_cstm_last_printed[0] & 0x20) == 0) //Print this once and stop + { + //Main thing + alphabet_setup(String, 0, true); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 1, true); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 2, true); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 3, true); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 4, true); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 5, true); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x20; //Printed flag + } + break; + case 0xB: //Alphabet 2 + if((m2_cstm_last_printed[0] & 0x40) == 0) //Print this once and stop + { + //Main thing + alphabet_setup(String, 0, false); + print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 1, false); + print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 2, false); + print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 3, false); + print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 4, true); + print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); + alphabet_setup(String, 5, true); + print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x40; //Printed flag + } + + break; + case 0xC: //Alphabet 3 - Won't use + + break; + case 0xD: //Is this okay? Yes No + summary_setup(String, 0); + print_file_string(0xC, 5, 0x40, String, window_selector, windowX, windowY); + summary_setup(String, 1); + print_file_string(0xC, 0xB, 0x40, String, window_selector, windowX, windowY); + summary_setup(String, 2); + print_file_string(0x1, 0x11, 0x40, String, window_selector, windowX, windowY); + m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. + break; + default: //File select string, already printed + break; + } + +} + + +void format_file_cc(FILE_SELECT *file, int *index, byte cmd) +{ + file->formatted_str[(*index)++] = 0xFE; + file->formatted_str[(*index)++] = cmd; +} + +void format_file_string(FILE_SELECT *file) +{ + int index = 0; + + // Slot + int slot = file->slot + 1; + file->formatted_str[index++] = (byte)(slot + ZERO); + file->formatted_str[index++] = encode_ascii(':'); + file->formatted_str[index++] = encode_ascii(' '); + + if (file->status != 0) + { + char startNewStr[] = "Start New Game"; + for (int i = 0; i < (sizeof(startNewStr) - 1); i++) + file->formatted_str[index++] = encode_ascii(startNewStr[i]); + + file->formatted_str[index++] = 0xFF; + return; + } + + // Name + for (int i = 0; i < 5; i++) + { + byte name_chr = file->ness_name[i]; + + if (name_chr != 0xFF) + file->formatted_str[index++] = name_chr; + else + file->formatted_str[index++] = encode_ascii(' '); + } + + // Re-position + format_file_cc(file, &index, CUSTOMCC_SET_X); + file->formatted_str[index++] = 80; + + // Level + char levelStr[] = "Level: "; + for (int i = 0; i < (sizeof(levelStr) - 1); i++) + file->formatted_str[index++] = encode_ascii(levelStr[i]); + + int level = file->ness_level; + int ones = m2_remainder(level, 10); + int tens = m2_div(level, 10); + + if (tens > 0) + file->formatted_str[index++] = tens + ZERO; + + file->formatted_str[index++] = ones + ZERO; + + // Re-position + format_file_cc(file, &index, CUSTOMCC_SET_X); + file->formatted_str[index++] = 128; + + // Text speed + char textSpeedStr[] = "Text Speed: "; + for (int i = 0; i < (sizeof(textSpeedStr) - 1); i++) + file->formatted_str[index++] = encode_ascii(textSpeedStr[i]); + + char speedStrs[][7] = { + "Fast", + "Medium", + "Slow" + }; + + char *speedStr = speedStrs[file->text_speed]; + for (int i = 0; i < ascii_strlen(speedStr); i++) + file->formatted_str[index++] = encode_ascii(speedStr[i]); + + file->formatted_str[index++] = 0xFF; + + //Delete part + + index = (0x40 - 0x15); //Maximum length of this is 0x15 with the 0xFF. The strings do not collide... By 1 byte. If you were to remove this string's end (which you could), it would be by 2 bytes. + + file->formatted_str[index++] = (byte)(slot + ZERO); + file->formatted_str[index++] = encode_ascii(':'); + file->formatted_str[index++] = encode_ascii(' '); + + // Name + for (int i = 0; i < 5; i++) + { + byte name_chr = file->ness_name[i]; + + if (name_chr != 0xFF) + file->formatted_str[index++] = name_chr; + else + file->formatted_str[index++] = encode_ascii(' '); + } + + // Re-position + format_file_cc(file, &index, CUSTOMCC_SET_X); + file->formatted_str[index++] = (0x10 << 3); + + for (int i = 0; i < (sizeof(levelStr) - 1); i++) + file->formatted_str[index++] = encode_ascii(levelStr[i]); + + if (tens > 0) + file->formatted_str[index++] = tens + ZERO; + + file->formatted_str[index++] = ones + ZERO; + + file->formatted_str[index++] = 0xFF; +} \ No newline at end of file diff --git a/src/c/fileselect.h b/src/c/fileselect.h index d5b9efa..072a05c 100644 --- a/src/c/fileselect.h +++ b/src/c/fileselect.h @@ -2,6 +2,7 @@ #define HEADER_FILE_SELECT_INCLUDED #include "types.h" +#include "vwf.h" typedef struct FILE_SELECT { short status; // 0 = used, -1 = empty @@ -27,4 +28,46 @@ typedef struct FILE_SELECT { byte formatted_str[64]; } FILE_SELECT; +int get_tile_number_file_select(int x, int y); +void clear_tile_file(int x, int y, int pixels, int tile_offset_file); +void clear_rect_file(int x, int y, int width, int height, int pixels, int tile_offset_file, unsigned short *tilesetDestPtr); +unsigned short* getTilesetDest(int window_selector, int *width); +unsigned short getPaletteFromFileWindow(int x, int y, int window_selector); +void setPaletteToFileWindow(int x, int y, int window_selector, unsigned short palette); +void setPaletteToZero(int x, int y, int window_selector); +void setPaletteOnAllFile(int x, int y, byte *str, int length, int window_selector); +void wrapper_file_string_selection(int x, int y, int length, byte *str, int window_selector); +void setPaletteOnFile(int x, int y, int window_selector, FILE_SELECT *file); +void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY); +void wrapper_first_file_string(int x, int y, int length, byte *str, int window_selector); +void wrapper_delete_string(int x, int y, int length, byte *str, int window_selector); +void wrapper_name_string(int x, int y, int length, byte *str, int window_selector); +void wrapper_name_summary_string(int x, int y, int length, byte *str, int window_selector); +void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector); +void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr, int windowX); +void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY); +unsigned short setupCursorAction(int *Pos1, int *Pos2); +void setupCursorMovement(); +void setupCursorPosition(int *x, int *y); +void format_options_cc(char String[], int *index, byte cmd); +void options_setup(char String[], int selector); +void text_speed_setup(char String[], int selector); +void delete_setup(char String[], int selector); +void text_flavour_setup(char String[], int selector); +void description_setup(char String[], int selector); +void copy_setup(char String[]); +void letterSetup(char String[], int selector, bool capital, int *index); +void numbersSetup(char String[], int *index); +void alphabet_setup(char String[], int selector, bool capital); +void summary_setup(char String[], int selector); +void print_windows(int windowX, int windowY, int window_selector); +void format_file_cc(FILE_SELECT *file, int *index, byte cmd); +void format_file_string(FILE_SELECT *file); + +extern unsigned short m2_coord_table_file[]; +extern byte m2_cstm_last_printed[]; + +extern void cpufastset(void *source, void *dest, int mode); #endif + + diff --git a/src/c/vwf.c b/src/c/vwf.c index acb92d6..8e6ba49 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -2,7 +2,6 @@ #include "vwf.h" #include "number-selector.h" #include "locs.h" -#include "fileselect.h" byte decode_character(byte chr) { @@ -25,13 +24,6 @@ int get_tile_number(int x, int y) return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32; } -int get_tile_number_file_select(int x, int y) -{ - x--; - y--; - return m2_coord_table_file[x + ((y >> 1) * 28)] + (y & 1) * 32; -} - int get_tile_number_with_offset(int x, int y) { return get_tile_number(x, y) + *tile_offset; @@ -59,862 +51,6 @@ byte reduce_bit_depth(int row, int foreground) return lower | (upper << 4); } -// x,y: tile coordinates -void clear_tile_file(int x, int y, int pixels, int tile_offset_file) -{ - // Clear pixels - int tileIndex = get_tile_number_file_select(x, y) + tile_offset_file; - cpufastset(&pixels, &vram[tileIndex * 8], CPUFASTSET_FILL | 8); -} - -// x,y: tile coordinates -void clear_rect_file(int x, int y, int width, int height, int pixels, int tile_offset_file, unsigned short *tilesetDestPtr) -{ - for (int tileY = 0; tileY < height; tileY++) - { - for (int tileX = 0; tileX < width; tileX++) - { - if((tilesetDestPtr[x + tileX + ((y + tileY) * width)] & 0x3FF) != 0x95) - clear_tile_file(x + tileX, y + tileY, pixels, tile_offset_file); - else - break; - } - } -} - -void wrapper_file_string(int x, int y, int length, byte *str, int window_selector) -{ - m2_cstm_last_printed[0] = window_selector; //First time setup - print_file_string(x, y, length, str, window_selector, 1, 0); -} - -void wrapper_delete_string(int x, int y, int length, byte *str, int window_selector) -{ - print_file_string(x, y, length, str - 0x20 + 0x40 - 0x15, window_selector, 7, 0xA); -} - -void wrapper_name_string(int x, int y, int length, byte *str, int window_selector) -{ - char String[length]; - for(int i = 0; i < length; i++) - { - if(str[i] == 0xFD) - String[i] = 0x70; - else if(str[i] == 0xF1) - String[i] = 0x53; - else - String[i] = str[i]; - } - print_file_string(x, y, length, String, window_selector, 5, 0); -} - -void wrapper_name_summary_string(int x, int y, int length, byte *str, int window_selector) -{ - char String[length]; - for(int i = 0; i < length; i++) - String[i] = str[i]; - print_file_string(x, y, length, String, window_selector, 3, 0); -} - -void wrapper_copy_string(int x, int y, int length, byte *str, int window_selector) -{ - print_file_string(x, y, length, str, window_selector, 8, 0xC); -} - -int count_pixels(byte *str, int length) -{ - int pixels = 0; - for(int i = 0; i < length; i++) - if((str[i] != 0xFF) && (str[i] != 0xFE)) //The latter one is not really needed - pixels += (m2_widths_table[0][decode_character(str[i])] & 0xFF); - int tiles = pixels >> 3; - if((pixels & 7) != 0) - tiles +=1; - return tiles; -} - -void clearArr(int x, int y, int width, unsigned short *tilesetDestPtr, int windowX) -{ - for(int i = x; i < width + windowX - 2; i++) - { - if((tilesetDestPtr[i + (y * width)] & 0x3FF) != 0x95) - { - tilesetDestPtr[i + (y * width)] = 0x13F; - tilesetDestPtr[i + ((y+1) * width)] = 0x13F; - } - else - break; - } -} - -void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY) -{ - int *tilesetBasePtr = (int *)(0x82B79B4 + (window_selector * 20)); - int width = tilesetBasePtr[2]; - unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]); - tilesetDestPtr = tilesetDestPtr - windowX - (windowY * width); - clearArr(x + windowX, y + windowY, width, tilesetDestPtr, windowX); //Cleans all of the arrangements this line could ever use - - int pixelX = (x + windowX) * 8; - int pixelY = ((y + windowY) * 8) + 3; - int realmask = *palette_mask; - *palette_mask = 0; //File select is special and changes its palette_mask on the fly. - clear_rect_file(x + windowX, y + windowY, width, 2, 0x11111111, 0x400, tilesetDestPtr); //Clean the rectangle before printing - - for (int i = 0; i < length; i++) - { - byte chr = str[i]; - - if (chr == 0xFF) - { - break; // the game does something else here, haven't looked into what exactly - } - else if (chr == 0xFE) - { - // Define 0xFE as a control code - byte cmd = str[++i]; - switch (cmd) - { - case CUSTOMCC_ADD_X: - pixelX += str[++i]; - break; - - case CUSTOMCC_SET_X: - pixelX = str[++i]; - break; - } - continue; - } - - chr = decode_character(chr); - int pixels = print_character_with_callback( - chr, - pixelX, - pixelY, - 0, - 9, - vram + 0x2000, - &get_tile_number_file_select, - tilesetDestPtr, - width); - - pixelX += pixels; - } - *palette_mask = realmask; -} - -unsigned short setupCursorAction(int *Pos1, int *Pos2) -{ - int *a = (int *)0x3000024; - int *caller = (int *)a[0]; - int CursorX = caller[0xDA4 >> 2]; - int CursorY = caller[0xDA8 >> 2]; - int alphabet = caller[0xDAC >> 2]; - int *table = (int *)0x82B8FFC; //Address of the alphabet table - - int choice = 0; - int counter = 0; - - for(int i = 0; i < CursorY; i++) - { - if(i <= 4) - choice += 0xE; - else - choice += 3; - } - - choice += CursorX; - (*Pos1) = alphabet; - (*Pos2) = choice; - - unsigned short letter = (table[choice] >> (16 * alphabet)); - return letter; -} - -void setupCursorMovement() -{ - int *a = (int *)0x3000024; - int *caller = (int *)a[0]; - int CursorX = caller[0xDA4 >> 2]; - int CursorY = caller[0xDA8 >> 2]; - int yAxys = 0; - int xAxys = 0; - - // Check for pressing left or right - PAD_STATE state = *pad_state; - - if (state.right) - xAxys = 1; - else if (state.left) - xAxys = -1; - else if (state.up) - yAxys = -1; - else if(state.down) - yAxys = 1; - - if(xAxys != 0) - { - CursorX += xAxys; - switch(CursorY) - { - case 0: - case 1: - case 2: - if(CursorX < 0) - CursorX = 0xA; - if(CursorX > 0xA) - CursorX = 0; - break; - case 3: - if(CursorX < 0) - CursorX = 0xB; - if(CursorX > 0xB) - CursorX = 0; - break; - case 4: - if(CursorX < 0) - CursorX = 0x3; - if(CursorX > 0x3) - CursorX = 0; - break; - default: - if(CursorX < 0) - CursorX = 0x2; - if(CursorX > 0x2) - CursorX = 0; - break; - } - m2_soundeffect(0x1A7); - } - else if(yAxys != 0) - { - switch(CursorY) - { - case 0: - case 1: - case 2: - CursorY += yAxys; - if(CursorY < 0) - { - if((CursorX >= 0x9)) - { - CursorX = 2 + CursorX - 0x9; - CursorY = 4; - } - else if(CursorX == 0) - CursorY = 5; - else - CursorY = 3; - } - else if(CursorY == 3 && CursorX >= 0x9) - CursorX += 1; - break; - case 3: - CursorY += yAxys; - if(CursorY == 2 && CursorX >= 9) - CursorX -=1; - if(CursorY == 4) - { - if(CursorX <= 3) - CursorX = 0; - else if (CursorX <= 9) - CursorX = 1; - else - CursorX = 2 + CursorX - 0xA; - } - break; - case 4: - CursorY += yAxys; - if(CursorY == 3) - { - if(CursorX >= 2) - CursorX = 0xA + CursorX - 2; - if(CursorX == 1) - CursorX = 4; - } - if(CursorY == 5) - { - if(CursorX >= 2) - CursorX = 1; - else - CursorX = 0; - } - break; - default: - CursorY += yAxys; - if(CursorY == 4 && CursorX == 2) - CursorX = 3; - if(CursorY == 6) - { - if(CursorX == 0) - CursorY = 0; - else - CursorY = 5; - } - break; - } - m2_soundeffect(0x1A8); - } - - caller[0xDA4 >> 2] = CursorX; - caller[0xDA8 >> 2] = CursorY; -} - -void setupCursorPosition(int *x, int *y) -{ - int *a = (int *)0x3000024; - int *caller = (int *)a[0]; - int CursorX = caller[0xDA4 >> 2]; - int CursorY = caller[0xDA8 >> 2]; - (*x) = 0; - (*y) = 0; - if(CursorY <= 4) - { - (*y) = 2 + (CursorY << 1); - switch(CursorY) - { - case 0: - case 1: - case 2: - switch(CursorX) - { - case 9: - case 0xA: - (*x) = 23 + ((CursorX -9) << 1); - break; - default: - (*x) = 1 + (CursorX << 1); - break; - } - break; - case 3: - switch(CursorX) - { - case 0xA: - case 0xB: - (*x) = 23 + ((CursorX -0xA) << 1); - break; - default: - (*x) = 1 + (CursorX << 1); - break; - } - break; - default: - switch(CursorX) - { - case 0: - (*x) = 1; - break; - case 1: - (*x) = 8; - break; - case 2: - case 3: - (*x) = 23 + ((CursorX- 2) << 1); - break; - } - break; - } - } - else - { - (*y) = 14; - switch(CursorX) - { - case 0: - (*x) = 1; - break; - case 1: - (*x) = 18; - break; - default: - (*x) = 26; - break; - } - } -} - -void format_options_cc(char String[], int *index, byte cmd) -{ - String[(*index)++] = 0xFE; - String[(*index)++] = cmd; -} - -void options_setup(char String[]) -{ - int index = 0; - char Continue[] = "Continue"; - for(int i = 0; i < (sizeof(Continue) -1); i++) - String[index++] = encode_ascii(Continue[i]); - - // Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0xC << 3); - - char Copy[] = "Copy"; - for(int i = 0; i < (sizeof(Copy) -1); i++) - String[index++] = encode_ascii(Copy[i]); - - // Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x10 << 3); - - char Delete[] = "Delete"; - for(int i = 0; i < (sizeof(Delete) -1); i++) - String[index++] = encode_ascii(Delete[i]); - - // Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x15 << 3); - - char Setup[] = "Set Up"; - for(int i = 0; i < (sizeof(Setup) -1); i++) - String[index++] = encode_ascii(Setup[i]); - - //END - String[index++] = 0xFF; -} - -void text_speed_setup(char String[], int selector) -{ - int index = 0; - char Text_Speed[] = "Please select text speed."; - char Medium[] = "Medium"; - char Fast[] = "Fast"; - char Slow[] = "Slow"; - switch(selector) - { - case 0: - for(int i = 0; i < (sizeof(Text_Speed) -1); i++) - String[index++] = encode_ascii(Text_Speed[i]); - break; - case 1: - for(int i = 0; i < (sizeof(Fast) -1); i++) - String[index++] = encode_ascii(Fast[i]); - break; - case 2: - for(int i = 0; i < (sizeof(Medium) -1); i++) - String[index++] = encode_ascii(Medium[i]); - break; - default: - for(int i = 0; i < (sizeof(Slow) -1); i++) - String[index++] = encode_ascii(Slow[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void delete_setup(char String[], int selector) -{ - int index = 0; - char Delete[] = "Are you sure you want to delete?"; - char No[] = "No"; - char Yes[] = "Yes"; - switch(selector) - { - case 0: - for(int i = 0; i < (sizeof(Delete) -1); i++) - String[index++] = encode_ascii(Delete[i]); - break; - case 1: - for(int i = 0; i < (sizeof(No) -1); i++) - String[index++] = encode_ascii(No[i]); - break; - default: - for(int i = 0; i < (sizeof(Yes) -1); i++) - String[index++] = encode_ascii(Yes[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void text_flavour_setup(char String[], int selector) -{ - int index = 0; - char Text_Flavour_1[] = "Which style of windows"; - char Text_Flavour_2[] = "do you prefer?"; - char Plain[] = "Plain flavor"; - char Mint[] = "Mint flavor"; - char Strawberry[] = "Strawberry flavor"; - char Banana[] = "Banana flavor"; - char Peanut[] = "Peanut flavor"; - switch(selector) - { - case 0: - for(int i = 0; i < (sizeof(Text_Flavour_1) -1); i++) - String[index++] = encode_ascii(Text_Flavour_1[i]); - break; - case 1: - for(int i = 0; i < (sizeof(Text_Flavour_2) -1); i++) - String[index++] = encode_ascii(Text_Flavour_2[i]); - break; - case 2: - for(int i = 0; i < (sizeof(Plain) -1); i++) - String[index++] = encode_ascii(Plain[i]); - break; - case 3: - for(int i = 0; i < (sizeof(Mint) -1); i++) - String[index++] = encode_ascii(Mint[i]); - break; - case 4: - for(int i = 0; i < (sizeof(Strawberry) -1); i++) - String[index++] = encode_ascii(Strawberry[i]); - break; - case 5: - for(int i = 0; i < (sizeof(Banana) -1); i++) - String[index++] = encode_ascii(Banana[i]); - break; - default: - for(int i = 0; i < (sizeof(Peanut) -1); i++) - String[index++] = encode_ascii(Peanut[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void description_setup(char String[], int selector) -{ - int index = 0; - char Ness[] = "Please name him."; - char Paula[] = "Name her, too."; - char Jeff[] = "Name your friend."; - char Poo[] = "Name another friend."; - char King[] = "Name your pet."; - char FavFood[] = "Favorite homemade food?"; - char FavThing[] = "What's your favorite thing?"; - switch(selector) - { - case 3: - for(int i = 0; i < (sizeof(Ness) -1); i++) - String[index++] = encode_ascii(Ness[i]); - break; - case 4: - for(int i = 0; i < (sizeof(Paula) -1); i++) - String[index++] = encode_ascii(Paula[i]); - break; - case 5: - for(int i = 0; i < (sizeof(Jeff) -1); i++) - String[index++] = encode_ascii(Jeff[i]); - break; - case 6: - for(int i = 0; i < (sizeof(Poo) -1); i++) - String[index++] = encode_ascii(Poo[i]); - break; - case 7: - for(int i = 0; i < (sizeof(King) -1); i++) - String[index++] = encode_ascii(King[i]); - break; - case 8: - for(int i = 0; i < (sizeof(FavFood) -1); i++) - String[index++] = encode_ascii(FavFood[i]); - break; - default: - for(int i = 0; i < (sizeof(FavThing) -1); i++) - String[index++] = encode_ascii(FavThing[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void copy_setup(char String[]) -{ - int index = 0; - char Copy[] = "Copy to where?"; - for(int i = 0; i < (sizeof(Copy) -1); i++) - String[index++] = encode_ascii(Copy[i]); - //END - String[index++] = 0xFF; -} - -void letterSetup(char String[], int selector, bool capital, int *index) -{ - char base = capital ? 'A' : 'a'; - int value = 9 - (selector >> 1); - for(int i = 0; i < value; i++) - { - String[(*index)++] = encode_ascii(base + i + (selector * 9)); - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - if(i != value -1) - String[(*index)++] = (2 * (i + 2)) << 3; - else - String[(*index)++] = (24) << 3; - } - switch(selector) - { - case 0: - String[(*index)++] = 93; - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - String[(*index)++] = (26) << 3; - String[(*index)++] = 83; - break; - case 1: - String[(*index)++] = 87; - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - String[(*index)++] = (26) << 3; - String[(*index)++] = 174; - break; - default: - String[(*index)++] = 94; - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - String[(*index)++] = (26) << 3; - String[(*index)++] = 95; - break; - } -} -void numbersSetup(char String[], int *index) -{ - char base = '0'; - for(int i = 0; i < 10; i++) - { - String[(*index)++] = encode_ascii(base + i); - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - if(i != 9) - String[(*index)++] = (2 * (i + 2)) << 3; - else - String[(*index)++] = (24) << 3; - } - String[(*index)++] = 81; - // Re-position - format_options_cc(String, &(*index), CUSTOMCC_SET_X); - String[(*index)++] = (26) << 3; - String[(*index)++] = 0xAC; -} - -void alphabet_setup(char String[], int selector, bool capital) -{ - int index = 0; - char Capital[] = "CAPITAL"; - char Small[] = "small"; - char DontCare[] = "Don't Care"; - char Backspace[] = "Backspace"; - char Ok[] = "OK"; - switch(selector) - { - case 0: - case 1: - case 2: - letterSetup(String, selector, capital, &index); - break; - case 3: - numbersSetup(String, &index); - break; - case 4: - for(int i = 0; i < (sizeof(Capital) -1); i++) - String[index++] = encode_ascii(Capital[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (9) << 3; - for(int i = 0; i < (sizeof(Small) -1); i++) - String[index++] = encode_ascii(Small[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (24) << 3; - String[index++] = 111; - // Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (26) << 3; - String[index++] = 0xAF; - break; - default: - for(int i = 0; i < (sizeof(DontCare) -1); i++) - String[index++] = encode_ascii(DontCare[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (19) << 3; - for(int i = 0; i < (sizeof(Backspace) -1); i++) - String[index++] = encode_ascii(Backspace[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (27) << 3; - for(int i = 0; i < (sizeof(Ok) -1); i++) - String[index++] = encode_ascii(Ok[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void summary_setup(char String[], int selector) -{ - int index = 0; - char FavFood[] = "Favorite food:"; - char FavThing[] = "Coolest thing:"; - char AreYouSure[] = "Are you sure?"; - char Yep[] = "Yep"; - char Nope[] = "Nope"; - switch(selector) - { - case 0: - for(int i = 0; i < (sizeof(FavFood) -1); i++) - String[index++] = encode_ascii(FavFood[i]); - break; - case 1: - for(int i = 0; i < (sizeof(FavThing) -1); i++) - String[index++] = encode_ascii(FavThing[i]); - break; - default: - for(int i = 0; i < (sizeof(AreYouSure) -1); i++) - String[index++] = encode_ascii(AreYouSure[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x13) << 3; - for(int i = 0; i < (sizeof(Yep) -1); i++) - String[index++] = encode_ascii(Yep[i]); - //Re-position - format_options_cc(String, &index, CUSTOMCC_SET_X); - String[index++] = (0x17) << 3; - for(int i = 0; i < (sizeof(Nope) -1); i++) - String[index++] = encode_ascii(Nope[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void print_windows(int windowX, int windowY, int window_selector) -{ - char String[64]; - switch(window_selector) - { - case 0x10: //Delete - delete_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); - delete_setup(String, 1); - print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); - delete_setup(String, 2); - print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); - break; - case 0xE: //Options - options_setup(String); - print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); - break; - case 1: //Text Speed - if(((m2_cstm_last_printed[0] & 0x1F) != 1) && ((m2_cstm_last_printed[0] & 0x80) == 0)) //If Text Flavour is printed, don't reprint it - { - text_speed_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); - text_speed_setup(String, 1); - print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); - text_speed_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); - text_speed_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); - } - else if ((m2_cstm_last_printed[0] & 0x80) != 0) //This has not been printed. Instead Text Flavour has been. - m2_cstm_last_printed[0] = 2; - break; - case 0x2: //Text Flavour - if((m2_cstm_last_printed[0] & 0x1F) != 2){ - text_flavour_setup(String, 0); - print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 1); - print_file_string(1, 3, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 4); - print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 5); - print_file_string(2, 11, 0x40, String, window_selector, windowX, windowY); - text_flavour_setup(String, 6); - print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. - } - break; - case 0xF: //Copy - copy_setup(String); - print_file_string(1, 1, 0x40, String, window_selector, windowX, windowY); - break; - case 0x3: //Ness' name + description - case 0x4: //Paula's name + description - case 0x5: //Jeff's name + description - case 0x6: //Poo's name + description - case 0x7: //King's name + description - case 0x8: //FavFood's name + description - case 0x9: //FavThing's name + description - if((m2_cstm_last_printed[0] & 0x1F) != window_selector){ - description_setup(String, window_selector); - print_file_string(9, 1, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector | (m2_cstm_last_printed[0] & 0x20); - } - break; - case 0xA: //Alphabet 1 - if((m2_cstm_last_printed[0] & 0x20) == 0) //Print this once and stop - { - //Main thing - alphabet_setup(String, 0, true); - print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 1, true); - print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 2, true); - print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 3, true); - print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x20; //Printed flag - } - break; - case 0xB: //Alphabet 2 - if((m2_cstm_last_printed[0] & 0x40) == 0) //Print this once and stop - { - //Main thing - alphabet_setup(String, 0, false); - print_file_string(2, 1, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 1, false); - print_file_string(2, 3, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 2, false); - print_file_string(2, 5, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 3, false); - print_file_string(2, 7, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, windowX, windowY); - alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = (m2_cstm_last_printed[0] & 0x1F) | 0x40; //Printed flag - } - - break; - case 0xC: //Alphabet 3 - Won't use - - break; - case 0xD: //Is this okay? Yes No - summary_setup(String, 0); - print_file_string(0xC, 5, 0x40, String, window_selector, windowX, windowY); - summary_setup(String, 1); - print_file_string(0xC, 0xB, 0x40, String, window_selector, windowX, windowY); - summary_setup(String, 2); - print_file_string(0x1, 0x11, 0x40, String, window_selector, windowX, windowY); - m2_cstm_last_printed[0] = window_selector; //Set the alphabet bit to 0. - break; - default: //File select string, already printed - break; - } - -} - - -void format_file_cc(FILE_SELECT *file, int *index, byte cmd) -{ - file->formatted_str[(*index)++] = 0xFE; - file->formatted_str[(*index)++] = cmd; -} - int ascii_strlen(char *str) { int len = 0; @@ -923,108 +59,40 @@ int ascii_strlen(char *str) return len; } -void format_file_string(FILE_SELECT *file) +int wrapper_count_pixels_to_tiles(byte *str, int length) { - int index = 0; + return count_pixels_to_tiles(str, length, 0); +} - // Slot - int slot = file->slot + 1; - file->formatted_str[index++] = (byte)(slot + ZERO); - file->formatted_str[index++] = encode_ascii(':'); - file->formatted_str[index++] = encode_ascii(' '); +int count_pixels_to_tiles(byte *str, int length, int startingPos) +{ + int pixels = startingPos; + for(int i = 0; i < length; i++) + { + if((str[i] != 0xFF) && (str[i] != 0xFE)) //The latter one is not really needed + pixels += (m2_widths_table[0][decode_character(str[i])] & 0xFF); + else if(str[i] == 0xFE) + { + // Define 0xFE as a control code + byte cmd = str[++i]; + switch (cmd) + { + case CUSTOMCC_ADD_X: + pixels += str[++i]; + break; - if (file->status != 0) - { - char startNewStr[] = "Start New Game"; - for (int i = 0; i < (sizeof(startNewStr) - 1); i++) - file->formatted_str[index++] = encode_ascii(startNewStr[i]); - - file->formatted_str[index++] = 0xFF; - return; - } - - // Name - for (int i = 0; i < 5; i++) - { - byte name_chr = file->ness_name[i]; - - if (name_chr != 0xFF) - file->formatted_str[index++] = name_chr; - else - file->formatted_str[index++] = encode_ascii(' '); - } - - // Re-position - format_file_cc(file, &index, CUSTOMCC_SET_X); - file->formatted_str[index++] = 76; - - // Level - char levelStr[] = "Level: "; - for (int i = 0; i < (sizeof(levelStr) - 1); i++) - file->formatted_str[index++] = encode_ascii(levelStr[i]); - - int level = file->ness_level; - int ones = m2_remainder(level, 10); - int tens = m2_div(level, 10); - - if (tens > 0) - file->formatted_str[index++] = tens + ZERO; - - file->formatted_str[index++] = ones + ZERO; - - // Re-position - format_file_cc(file, &index, CUSTOMCC_SET_X); - file->formatted_str[index++] = 128; - - // Text speed - char textSpeedStr[] = "Text Speed: "; - for (int i = 0; i < (sizeof(textSpeedStr) - 1); i++) - file->formatted_str[index++] = encode_ascii(textSpeedStr[i]); - - char speedStrs[][7] = { - "Fast", - "Medium", - "Slow" - }; - - char *speedStr = speedStrs[file->text_speed]; - for (int i = 0; i < ascii_strlen(speedStr); i++) - file->formatted_str[index++] = encode_ascii(speedStr[i]); - - file->formatted_str[index++] = 0xFF; - - //Delete part - - index = (0x40 - 0x15); //Maximum length of this is 0x15 with the 0xFF. The strings do not collide... By 1 byte. If you were to remove this string's end (which you could), it would be by 2 bytes. - - file->formatted_str[index++] = (byte)(slot + ZERO); - file->formatted_str[index++] = encode_ascii(':'); - file->formatted_str[index++] = encode_ascii(' '); - - // Name - for (int i = 0; i < 5; i++) - { - byte name_chr = file->ness_name[i]; - - if (name_chr != 0xFF) - file->formatted_str[index++] = name_chr; - else - file->formatted_str[index++] = encode_ascii(' '); - } - - // Re-position - format_file_cc(file, &index, CUSTOMCC_SET_X); - file->formatted_str[index++] = (0x10 << 3); - - for (int i = 0; i < (sizeof(levelStr) - 1); i++) - file->formatted_str[index++] = encode_ascii(levelStr[i]); - - if (tens > 0) - file->formatted_str[index++] = tens + ZERO; - - file->formatted_str[index++] = ones + ZERO; - - file->formatted_str[index++] = 0xFF; + case CUSTOMCC_SET_X: + pixels = str[++i]; + break; + } + } + else + break; + } + int tiles = (pixels - startingPos)>> 3; + if((pixels & 7) != 0) + tiles +=1; + return tiles; } byte print_character(byte chr, int x, int y) diff --git a/src/c/vwf.h b/src/c/vwf.h index b4af825..3a2d266 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -1,6 +1,5 @@ #include "types.h" #include "pc.h" -#include "fileselect.h" #define NULL (0) #define QUESTION_MARK 0x1F @@ -28,7 +27,9 @@ byte decode_character(byte chr); byte encode_ascii(char chr); int get_tile_number(int x, int y); -int count_pixels(byte *str, int length); +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); int expand_bit_depth(byte row, int foreground); byte reduce_bit_depth(int row, int foreground); byte print_character(byte chr, int x, int y); @@ -68,12 +69,8 @@ void print_number_menu_current(byte digit, WINDOW* window); void clear_number_menu(WINDOW* window); void format_cash_window(int value, int padding, byte* str); void handle_first_window(WINDOW* window); -void print_file_string(int x, int y, int length, byte *str, int window_selector, int windowX, int windowY); -void wrapper_file_string(int x, int y, int length, byte *str, int window_selector); -void format_file_string(FILE_SELECT *file); extern unsigned short m2_coord_table[]; -extern unsigned short m2_coord_table_file[]; extern int m2_bits_to_nybbles[]; extern byte m2_nybbles_to_bits[]; extern byte *m2_font_table[]; diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 98e6c1a..73408cb 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1056,7 +1056,7 @@ nop .org 0x8003998 :: mov r0,1 // new window x .org 0x8003F92 :: mov r0,1 .org 0x80053DC :: mov r0,1 -.org 0x8003A04 :: mov r0,1 +.org 0x8003A04 :: bl _3a04_highlight_file //Changes window position and makes sure the file is properly highlighted .org 0x8003B40 :: mov r0,0x10 // new cursor x .org 0x86DB070 :: .incbin "data/m2-fileselect-template.bin" @@ -1068,20 +1068,26 @@ nop .org 0x8002284 :: bl format_file_string // Printing -.org 0x80038CC :: mov r2,0x40 :: bl wrapper_file_string -.org 0x80038DE :: mov r2,0x40 :: bl wrapper_file_string -.org 0x80038F2 :: mov r2,0x40 :: bl wrapper_file_string +.org 0x80038CC :: mov r2,0x40 :: bl wrapper_first_file_string +.org 0x80038DE :: mov r2,0x40 :: bl wrapper_first_file_string +.org 0x80038F2 :: mov r2,0x40 :: bl wrapper_first_file_string // Bump file select cursor up by 3 pixels - Not needed now that the text is 3 pixels lower //.org 0x8003844 :: add r0,r5,1 // File select options +.org 0x8003F78 :: bl _3f78_highlight_file //Keeps highlight consistent when changing palette in the text flavour window +.org 0x8004072 :: bl _40e2_cursor_X //Removing highlight position +.org 0x8004080 :: mov r3,#4 //Remove highlight of 4 tiles maximum .org 0x8004092 :: bl _4092_print_window //Printing -.org 0x80041D4 :: bl _41D4_cursor_X //New cursor's X +.org 0x80040E2 :: bl _40e2_cursor_X //Highlight position +.org 0x80040F4 :: mov r3,#4 //Print highlight of 4 tiles maximum +.org 0x80041D4 :: bl _41d4_cursor_X //New cursor's X //Text Speed options .org 0x8003BBC :: bl _4092_print_window //Printing .org 0x8003FA2 :: bl _4092_print_window +.org 0x8003F8C :: mov r3,#4 //Print highlight of 4 tiles maximum .org 0x8003E86 :: bl _3e86_special_setup //Avoid printing when not necessary .org 0x8003EF2 :: bl _3e86_special_setup //Avoid printing when not necessary .org 0x82B79D0 :: dw 0x10 //new window width @@ -1145,9 +1151,9 @@ nop .org 0x800556A :: nop :: nop //Sends to a bunch of 0xFF .org 0x8005530 :: mov r0,#0x11 //New x for King's name .org 0x8005536 :: bl wrapper_name_summary_string //Printing King's name -.org 0x8005578 :: bl count_pixels :: mov r2,#6 :: mov r4,#0x17 :: sub r0,r4,r0 //Count length of Food's name in tiles +.org 0x8005578 :: bl wrapper_count_pixels_to_tiles :: mov r2,#6 :: mov r4,#0x17 :: sub r0,r4,r0 //Count length of Food's name in tiles .org 0x8005588 :: bl wrapper_name_summary_string //Printing Food's name -.org 0x8005596 :: bl count_pixels :: mov r2,#6 :: sub r4,r4,r0 //Count length of Food's name in tiles +.org 0x8005596 :: bl wrapper_count_pixels_to_tiles :: mov r2,#6 :: sub r4,r4,r0 //Count length of Thing's name in tiles .org 0x80055A6 :: bl wrapper_name_summary_string //Printing Thing's name .org 0x80056F0 :: add r0,#0x90 //New cursor's X .org 0x86DBC6C :: .incbin "data/m2-summary-template.bin" diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index f953859..5062e51 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -1602,10 +1602,11 @@ mov r2,#0 mov r3,#0 pop {pc} -//============================================================================== -//X cursor for the Options submenu in the File Select window -_41D4_cursor_X: -push {lr} +// +//X cursor for the Options submenu position +_position_X_Options: +push {lr} + cmp r0,#1 bne @@next1 mov r0,#5 @@ -1624,6 +1625,23 @@ b @@end mov r0,#20 @@end: +pop {pc} + +//============================================================================== +//Sets X for highlighting the Options submenu in the File Select window +_40e2_cursor_X: +push {lr} +mov r0,r1 +bl _position_X_Options +sub r1,r0,#3 +mov r0,#2 +pop {pc} + +//============================================================================== +//Sets X cursor for the Options submenu in the File Select window +_41d4_cursor_X: +push {lr} +bl _position_X_Options lsl r0,r0,#3 pop {pc} @@ -1656,9 +1674,11 @@ pop {pc} //Loads and prints the text lines for the file select main window _setup_file_strings: push {r4-r5,lr} -add sp,#-4 +add sp,#-8 ldr r5,=#0x3000024 ldr r2,[r5,#0] +ldr r4,[r2,#4] +str r4,[sp,#4] //Save this here mov r4,#0 str r4,[r2,#4] mov r0,#0 @@ -1675,7 +1695,7 @@ str r4,[sp,#0] mov r0,#2 mov r1,#1 mov r2,#0x40 -bl wrapper_file_string +bl wrapper_file_string_selection ldr r3,[r5,#0] ldr r0,=#0x454 add r3,r3,r0 @@ -1683,7 +1703,7 @@ str r4,[sp,#0] mov r0,#2 mov r1,#3 mov r2,#0x40 -bl wrapper_file_string +bl wrapper_file_string_selection ldr r3,[r5,#0] mov r0,#0xD3 lsl r0,r0,#3 @@ -1692,8 +1712,15 @@ str r4,[sp,#0] mov r0,#2 mov r1,#5 mov r2,#0x40 -bl wrapper_file_string -add sp,#4 +bl wrapper_file_string_selection +mov r0,#1 +mov r1,#0 +mov r2,#0 +bl 0x800341C +ldr r2,[r5,#0] +ldr r4,[sp,#4] +str r4,[r2,#4] //Restore this +add sp,#8 pop {r4-r5,pc} .pool @@ -1737,4 +1764,39 @@ orr r1,r2 strb r1,[r0,#0] pop {r0-r2} bl 0x8003F44 +pop {pc} + +//============================================================================== +//Highlights all of the file string with the proper palette +_highlight_file: +push {lr} +mov r0,#2 +ldr r1,=#0x3000024 //Load in r1 the y co-ordinate +ldr r1,[r1,#0] +ldr r1,[r1,#8] +lsl r1,r1,#1 +add r1,#1 +mov r2,#0 +mov r3,r4 +bl setPaletteOnFile +pop {pc} + +.pool + +//============================================================================== +//File highlighting for the up-down arrows in the text flavour window +_3f78_highlight_file: +push {lr} +bl _highlight_file +mov r0,#4 //Clobbered code +ldsh r2,[r4,r0] +pop {pc} + +//============================================================================== +//File highlighting for when a file is selected +_3a04_highlight_file: +push {lr} +bl _highlight_file +mov r0,#1 //Clobbered code +mov r1,#0 pop {pc} \ No newline at end of file