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 c195354..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) { @@ -22,9 +21,7 @@ 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_with_offset(int x, int y) @@ -54,640 +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(x, y) + tile_offset_file; - if(((tileIndex << 3) != (0xC9C0 >> 2)) && ((tileIndex << 3) != (0xC9E0 >> 2))) - 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, 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); -} - -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, 0x7800); -} - -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, 0x2800); -} - -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 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++) - { - 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 offset) -{ - 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 - - int pixelX = x * 8; - int pixelY = (y * 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 - - 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 + (offset >> 2), - &get_tile_number, - tilesetDestPtr, - width, - (offset >>5)); - - pixelX += pixels; - } - *palette_mask = realmask; -} - -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++] = 64; - - 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++] = 97; - - 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++] = 137; - - 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++] = (0x10) << 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; - for(int i = 0; i < (sizeof(Nope) -1); i++) - String[index++] = encode_ascii(Nope[i]); - break; - } - //END - String[index++] = 0xFF; -} - -void print_windows(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); - delete_setup(String, 1); - print_file_string(2, 5, 0x40, String, window_selector, offset); - delete_setup(String, 2); - print_file_string(2, 7, 0x40, String, window_selector, offset); - 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); - 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); - text_speed_setup(String, 1); - print_file_string(2, 3, 0x40, String, window_selector, offset); - text_speed_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, offset); - text_speed_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, offset); - 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); - text_flavour_setup(String, 1); - print_file_string(1, 3, 0x40, String, window_selector, offset); - text_flavour_setup(String, 2); - print_file_string(2, 5, 0x40, String, window_selector, offset); - text_flavour_setup(String, 3); - print_file_string(2, 7, 0x40, String, window_selector, offset); - text_flavour_setup(String, 4); - print_file_string(2, 9, 0x40, String, window_selector, offset); - text_flavour_setup(String, 5); - print_file_string(2, 11, 0x40, String, window_selector, offset); - text_flavour_setup(String, 6); - print_file_string(2, 13, 0x40, String, window_selector, offset); - 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); - 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){ - 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); - } - break; - case 0xA: //Alphabet 1 - 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); - alphabet_setup(String, 1, true); - print_file_string(2, 3, 0x40, String, window_selector, offset); - alphabet_setup(String, 2, true); - print_file_string(2, 5, 0x40, String, window_selector, offset); - alphabet_setup(String, 3, true); - print_file_string(2, 7, 0x40, String, window_selector, offset); - alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, offset); - alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, offset); - 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 - offset = 0x2800; - alphabet_setup(String, 0, false); - print_file_string(2, 1, 0x40, String, window_selector, offset); - alphabet_setup(String, 1, false); - print_file_string(2, 3, 0x40, String, window_selector, offset); - alphabet_setup(String, 2, false); - print_file_string(2, 5, 0x40, String, window_selector, offset); - alphabet_setup(String, 3, false); - print_file_string(2, 7, 0x40, String, window_selector, offset); - alphabet_setup(String, 4, true); - print_file_string(2, 9, 0x40, String, window_selector, offset); - alphabet_setup(String, 5, true); - print_file_string(2, 13, 0x40, String, window_selector, offset); - 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 - offset = 0x2800; - summary_setup(String, 0); - print_file_string(0xC, 5, 0x40, String, window_selector, offset); - summary_setup(String, 1); - print_file_string(0xC, 0xB, 0x40, String, window_selector, offset); - summary_setup(String, 2); - print_file_string(0x1, 0x11, 0x40, String, window_selector, offset); - 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; @@ -696,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++] = 72; - - 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) @@ -821,12 +116,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. @@ -864,7 +159,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]; @@ -916,9 +211,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) @@ -951,9 +246,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 77539e4..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); @@ -38,7 +39,7 @@ void print_special_character(int tile, int x, int y); void map_special_character(unsigned short tile, int x, int y); void map_tile(unsigned short tile, int x, int y); byte print_character_with_callback(byte chr, int x, int y, int font, int foreground, - int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth, int 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,9 +69,6 @@ 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 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 int m2_bits_to_nybbles[]; @@ -93,3 +91,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 0000000..a91773e Binary files /dev/null and b/src/data/m2-alphabet-table.bin differ 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 0000000..0daa8b1 Binary files /dev/null and b/src/data/m2-coord-table-file-select.bin differ diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 7831544..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,28 @@ 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 .org 0x86DB0FC :: .incbin "data/m2-textspeed-template.bin" @@ -1095,6 +1103,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 +1118,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" @@ -1124,6 +1134,12 @@ 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" +.org 0x8002322 :: bl _2322_setup_windowing //Summary .org 0x80055B0 :: bl _4092_print_window //Printing @@ -1135,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" @@ -1215,6 +1231,9 @@ m2_nybbles_to_bits: m2_enemy_attributes: .incbin "data/m2-enemy-attributes.bin" +m2_coord_table_file: +.incbin "data/m2-coord-table-file-select.bin" + //============================================================================== // Existing subroutines/data //============================================================================== @@ -1279,8 +1298,8 @@ m2_enemy_attributes: .definelabel m2_curhpwindow_down ,0x80D41D8 .definelabel m2_div ,0x80F49D8 .definelabel m2_remainder ,0x80F4A70 -.definelabel m2_items ,0x8B1D62C .definelabel m2_default_names ,0x82B9330 +.definelabel m2_items ,0x8B1D62C //============================================================================== // Code files diff --git a/src/m2-vwf-entries.asm b/src/m2-vwf-entries.asm index e4e42d2..5062e51 100644 --- a/src/m2-vwf-entries.asm +++ b/src/m2-vwf-entries.asm @@ -1586,7 +1586,6 @@ pop {r5,pc} _4092_print_window: push {lr} push {r0-r4} -mov r0,r2 bl print_windows pop {r0-r4} bl 0x800341C @@ -1596,16 +1595,18 @@ pop {pc} _4298_print_window: push {lr} push {r0-r4} -ldr r0,[sp,#0x20] +ldr r2,[sp,#0x20] bl print_windows pop {r0-r4} mov r2,#0 mov r3,#0 pop {pc} -//============================================================================== -_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,10 +1625,28 @@ 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} //============================================================================== +//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 @@ -1635,4 +1654,149 @@ mov r10,r0 ldr r1,=#0x82B7FF8 pop {pc} -.pool \ No newline at end of file +.pool + +//============================================================================== +//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,#-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 +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_selection +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_selection +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_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 + +//============================================================================== +//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 +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 +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} + +//============================================================================== +//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} + +//============================================================================== +//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