diff --git a/src/c/vwf.c b/src/c/vwf.c index 56c8c75..1accc09 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -69,6 +69,97 @@ byte reduce_bit_depth(int row, int foregroundRow) return lower | (upper << 4); } +//The order is swapped in order to make this faster +//Doing the bottom tile directly saves some cycles +void reduce_bit_depth_sp(int* TileRows, int* bufferValues) +{ + int* bottomTileRows = TileRows + (0x20 * 8); + int* bottomBufferValues = bufferValues + 0x40; + const int andValue = 0x11111111; + + //First value + unsigned int firstRow = *(TileRows++); + unsigned int secondRow = *(TileRows++); + unsigned int thirdRow = *(TileRows++); + unsigned int fourthRow = *(TileRows++); + + firstRow &= andValue; + secondRow &= andValue; + thirdRow &= andValue; + fourthRow &= andValue; + + unsigned int value = optimized_byte_4bpp_to_1bpp_table[(fourthRow >> 0xF) + (fourthRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(thirdRow >> 0xF) + (thirdRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(secondRow >> 0xF) + (secondRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(firstRow >> 0xF) + (firstRow & 0xFFFF)]; + *(bufferValues++) = value; + + //Second value + firstRow = *(TileRows++); + secondRow = *(TileRows++); + thirdRow = *(TileRows++); + fourthRow = *(TileRows); + + firstRow &= andValue; + secondRow &= andValue; + thirdRow &= andValue; + fourthRow &= andValue; + + value = optimized_byte_4bpp_to_1bpp_table[(fourthRow >> 0xF) + (fourthRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(thirdRow >> 0xF) + (thirdRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(secondRow >> 0xF) + (secondRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(firstRow >> 0xF) + (firstRow & 0xFFFF)]; + *(bufferValues) = value; + + //First value of bottom tile + firstRow = *(bottomTileRows++); + secondRow = *(bottomTileRows++); + thirdRow = *(bottomTileRows++); + fourthRow = *(bottomTileRows++); + + firstRow &= andValue; + secondRow &= andValue; + thirdRow &= andValue; + fourthRow &= andValue; + + value = optimized_byte_4bpp_to_1bpp_table[(fourthRow >> 0xF) + (fourthRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(thirdRow >> 0xF) + (thirdRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(secondRow >> 0xF) + (secondRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(firstRow >> 0xF) + (firstRow & 0xFFFF)]; + *(bottomBufferValues++) = value; + + //Second value of bottom tile - Is not used by the game + /* + firstRow = *(bottomTileRows++); + secondRow = *(bottomTileRows++); + thirdRow = *(bottomTileRows++); + fourthRow = *(bottomTileRows); + + firstRow &= andValue; + secondRow &= andValue; + thirdRow &= andValue; + fourthRow &= andValue; + + value = optimized_byte_4bpp_to_1bpp_table[(fourthRow >> 0xF) + (fourthRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(thirdRow >> 0xF) + (thirdRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(secondRow >> 0xF) + (secondRow & 0xFFFF)]; + value <<= 8; + value |= optimized_byte_4bpp_to_1bpp_table[(firstRow >> 0xF) + (firstRow & 0xFFFF)]; + *(bottomBufferValues) = value; + */ +} + byte getSex(byte character) { return character == 1 ? 1 : 0; //character 1 is Paula @@ -799,7 +890,7 @@ int print_menu_string(WINDOW* window) break; default: looping = false; - window->menu_text = NULL; //Otherwise it will keep printing indefinetly + window->menu_text = NULL; //Otherwise it will keep printing indefinetly break; } } @@ -1518,14 +1609,14 @@ int highlight_string(WINDOW* window, byte* str, unsigned short x, unsigned short //Highlights "Talk to" void highlight_talk_to() { - char Talk_to[] = "Talk to"; - byte str[0xA]; - int i; - for(i = 0; i < (sizeof(Talk_to) - 1); i++) - str[i] = encode_ascii(Talk_to[i]); - str[i++] = 0; - str[i] = 0xFF; - highlight_string(getWindow(0), str, 1, 0, true); + char Talk_to[] = "Talk to"; + byte str[0xA]; + int i; + for(i = 0; i < (sizeof(Talk_to) - 1); i++) + str[i] = encode_ascii(Talk_to[i]); + str[i++] = 0; + str[i] = 0xFF; + highlight_string(getWindow(0), str, 1, 0, true); } unsigned short printstr_hlight_buffer(WINDOW* window, byte* str, unsigned short x, unsigned short y, bool highlight) @@ -1887,114 +1978,246 @@ int print_alphabet_buffer(WINDOW* window) void load_pixels_overworld_buffer() { - byte* buffer = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)); - for(int i = 0; i < 8 * 0x1C; i++) + int tile = *tile_offset; + byte* buffer = (byte*)(OVERWORLD_BUFFER - (tile * TILESET_OFFSET_BUFFER_MULTIPLIER)); + int* topBufferValues = (int*)(&buffer[tile * 8]); + int* topTilePointer; + int nextValue = 0x20; + int i = 0; + while(i < (0x1C * 8)) { - //Doing this saves about 100k cycles during load - int tile = m2_coord_table[i] + *tile_offset; - int addedValue = (i >> 5) << 6; - int tile_buffer = (i & 0x1F) + addedValue + *tile_offset; - int foregroundRow = 0xFFFFFFFF; - //Reduce total amount of stores from 16 to 4 - int* bufferValues = (int*)(&buffer[(tile_buffer * 8)]); - unsigned int first_half; - unsigned int second_half; - first_half = reduce_bit_depth(vram[(tile * 8) + 0], foregroundRow); - first_half |= reduce_bit_depth(vram[(tile * 8) + 1], foregroundRow) << 8; - first_half |= reduce_bit_depth(vram[(tile * 8) + 2], foregroundRow) << 0x10; - first_half |= reduce_bit_depth(vram[(tile * 8) + 3], foregroundRow) << 0x18; - second_half = reduce_bit_depth(vram[(tile * 8) + 4], foregroundRow); - second_half |= reduce_bit_depth(vram[(tile * 8) + 5], foregroundRow) << 8; - second_half |= reduce_bit_depth(vram[(tile * 8) + 6], foregroundRow) << 0x10; - second_half |= reduce_bit_depth(vram[(tile * 8) + 7], foregroundRow) << 0x18; - bufferValues[0] = first_half; - bufferValues[1] = second_half; - bufferValues += 0x40; - tile += 0x20; - first_half = reduce_bit_depth(vram[(tile * 8) + 0], foregroundRow); - first_half |= reduce_bit_depth(vram[(tile * 8) + 1], foregroundRow) << 8; - first_half |= reduce_bit_depth(vram[(tile * 8) + 2], foregroundRow) << 0x10; - first_half |= reduce_bit_depth(vram[(tile * 8) + 3], foregroundRow) << 0x18; - second_half = reduce_bit_depth(vram[(tile * 8) + 4], foregroundRow); - second_half |= reduce_bit_depth(vram[(tile * 8) + 5], foregroundRow) << 8; - second_half |= reduce_bit_depth(vram[(tile * 8) + 6], foregroundRow) << 0x10; - second_half |= reduce_bit_depth(vram[(tile * 8) + 7], foregroundRow) << 0x18; - bufferValues[0] = first_half; - bufferValues[1] = second_half; + //Using pointers instead of values directly saves another 14k cycles. The total amount of cycles this routine now takes is about 92k + tile = m2_coord_table_fast_progression[i]; + int remainingTiles = tile >> 0xB; + tile = (tile & 0x7FF) + (*tile_offset); + topTilePointer = &vram[(tile * 8)]; + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + } + i++; + //Using "reduce_bit_depth_sp" reduced the total amount of cycles from 300k to 162k + reduce_bit_depth_sp(topTilePointer, topBufferValues); + topTilePointer += 8; + topBufferValues += 2; + while(remainingTiles > 0) + { + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + } + i++; + reduce_bit_depth_sp(topTilePointer, topBufferValues); + topTilePointer += 8; + topBufferValues += 2; + remainingTiles--; + } } } void store_pixels_overworld_buffer(int totalYs) { - byte* buffer = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)); + int tile = *tile_offset; + byte* buffer = (byte*)(OVERWORLD_BUFFER - (tile * TILESET_OFFSET_BUFFER_MULTIPLIER)); totalYs >>= 1; int total = totalYs * 0x1C; - for(int i = 0; i < total; i++) + int* topBufferValues = (int*)(&buffer[tile * 8]); + int* bottomBufferValues = topBufferValues + 0x40; + int* topTilePointer; + int* bottomTilePointer; + int* bits_to_nybbles_pointer = m2_bits_to_nybbles_fast; + int bits_to_nybbles_array[0x100]; + //It's convenient to copy the table in IWRAM (about 0x400 cycles) only if we have more than 0x55 total tiles to copy ((total * 0xC * 2) = total cycles used reading from EWRAM vs. (total * 0xC) + 0x400 = total cycles used writing to and reading from IWRAM) + //From a full copy it saves about 15k cycles + if(total >= 0x56) + { + cpufastset(bits_to_nybbles_pointer, bits_to_nybbles_array, 0x100); + bits_to_nybbles_pointer = bits_to_nybbles_array; + } + int nextValue = 0x20; + int i = 0; + while(i < total) { //Not using functions for the tile values saves about 30k cycles on average - int tile = m2_coord_table[i] + *tile_offset; - int addedValue = (i >> 5) << 6; - int tile_buffer = (i & 0x1F) + addedValue + *tile_offset; - int* bufferValues = (int*)(&buffer[(tile_buffer * 8)]); - unsigned int first_half = bufferValues[0]; - unsigned int second_half = bufferValues[1]; - vram[(tile * 8) + 0] = m2_bits_to_nybbles_fast[(first_half >> 0) & 0xFF]; - vram[(tile * 8) + 1] = m2_bits_to_nybbles_fast[(first_half >> 8) & 0xFF]; - vram[(tile * 8) + 2] = m2_bits_to_nybbles_fast[(first_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 3] = m2_bits_to_nybbles_fast[(first_half >> 0x18) & 0xFF]; - vram[(tile * 8) + 4] = m2_bits_to_nybbles_fast[(second_half >> 0) & 0xFF]; - vram[(tile * 8) + 5] = m2_bits_to_nybbles_fast[(second_half >> 8) & 0xFF]; - vram[(tile * 8) + 6] = m2_bits_to_nybbles_fast[(second_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 7] = m2_bits_to_nybbles_fast[(second_half >> 0x18) & 0xFF]; - //Do the tile right below (Saves about 50k cycles on average) - tile += 0x20; - bufferValues += 0x40; - first_half = bufferValues[0]; - second_half = bufferValues[1]; - vram[(tile * 8) + 0] = m2_bits_to_nybbles_fast[(first_half >> 0) & 0xFF]; - vram[(tile * 8) + 1] = m2_bits_to_nybbles_fast[(first_half >> 8) & 0xFF]; - vram[(tile * 8) + 2] = m2_bits_to_nybbles_fast[(first_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 3] = m2_bits_to_nybbles_fast[(first_half >> 0x18) & 0xFF]; - vram[(tile * 8) + 4] = m2_bits_to_nybbles_fast[(second_half >> 0) & 0xFF]; - vram[(tile * 8) + 5] = m2_bits_to_nybbles_fast[(second_half >> 8) & 0xFF]; - vram[(tile * 8) + 6] = m2_bits_to_nybbles_fast[(second_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 7] = m2_bits_to_nybbles_fast[(second_half >> 0x18) & 0xFF]; + //Using pointers + a way to keep track of subsequent tiles saves 50k cycles on average from a full copy + //m2_coord_table_fast_progression has the tile number and the number of tiles used without interruction after it in a single short + tile = m2_coord_table_fast_progression[i]; + int remainingTiles = tile >> 0xB; + tile = (tile & 0x7FF) + (*tile_offset); + topTilePointer = &vram[(tile * 8)]; + bottomTilePointer = topTilePointer + (0x20 * 8); + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + bottomBufferValues += 0x40; + } + i++; + unsigned int first_half = *(topBufferValues++); + unsigned int second_half = *(topBufferValues++); + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + first_half = *(bottomBufferValues++); + //second_half = *(bottomBufferValues++); + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + //Since those are unused + bottomBufferValues++; + bottomTilePointer += 4; + /* The game doesn't use these + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + */ + + while(remainingTiles > 0) + { + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + bottomBufferValues += 0x40; + } + i++; + first_half = *(topBufferValues++); + second_half = *(topBufferValues++); + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + first_half = *(bottomBufferValues++); + //second_half = *(bottomBufferValues++); + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + //Since those are unused + bottomBufferValues++; + bottomTilePointer += 4; + /* The game doesn't use these + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + */ + remainingTiles--; + } } } void store_pixels_overworld_buffer_totalTiles(int totalTiles) { - byte* buffer = (byte*)(OVERWORLD_BUFFER - ((*tile_offset) * TILESET_OFFSET_BUFFER_MULTIPLIER)); - for(int i = 0; i < totalTiles; i++) + int tile = *tile_offset; + byte* buffer = (byte*)(OVERWORLD_BUFFER - (tile * TILESET_OFFSET_BUFFER_MULTIPLIER)); + int* topBufferValues = (int*)(&buffer[tile * 8]); + int* bottomBufferValues = topBufferValues + 0x40; + int* topTilePointer; + int* bottomTilePointer; + int* bits_to_nybbles_pointer = m2_bits_to_nybbles_fast; + int bits_to_nybbles_array[0x100]; + //It's convenient to copy the table in IWRAM (about 0x400 cycles) only if we have more than 0x55 total tiles to copy ((total * 0xC * 2) = total cycles used reading from EWRAM vs. (total * 0xC) + 0x400 = total cycles used writing to and reading from IWRAM) + //From a full copy it saves about 15k cycles + if(totalTiles >= 0x56) + { + cpufastset(bits_to_nybbles_pointer, bits_to_nybbles_array, 0x100); + bits_to_nybbles_pointer = bits_to_nybbles_array; + } + int nextValue = 0x20; + int i = 0; + while(i < totalTiles) { //Not using functions for the tile values saves about 30k cycles on average - int tile = m2_coord_table[i] + *tile_offset; - int addedValue = (i >> 5) << 6; - int tile_buffer = (i & 0x1F) + addedValue + *tile_offset; - int* bufferValues = (int*)(&buffer[(tile_buffer * 8)]); - unsigned int first_half = bufferValues[0]; - unsigned int second_half = bufferValues[1]; - vram[(tile * 8) + 0] = m2_bits_to_nybbles_fast[(first_half >> 0) & 0xFF]; - vram[(tile * 8) + 1] = m2_bits_to_nybbles_fast[(first_half >> 8) & 0xFF]; - vram[(tile * 8) + 2] = m2_bits_to_nybbles_fast[(first_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 3] = m2_bits_to_nybbles_fast[(first_half >> 0x18) & 0xFF]; - vram[(tile * 8) + 4] = m2_bits_to_nybbles_fast[(second_half >> 0) & 0xFF]; - vram[(tile * 8) + 5] = m2_bits_to_nybbles_fast[(second_half >> 8) & 0xFF]; - vram[(tile * 8) + 6] = m2_bits_to_nybbles_fast[(second_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 7] = m2_bits_to_nybbles_fast[(second_half >> 0x18) & 0xFF]; - //Do the tile right below (Saves about 50k cycles on average) - tile += 0x20; - bufferValues += 0x40; - first_half = bufferValues[0]; - second_half = bufferValues[1]; - vram[(tile * 8) + 0] = m2_bits_to_nybbles_fast[(first_half >> 0) & 0xFF]; - vram[(tile * 8) + 1] = m2_bits_to_nybbles_fast[(first_half >> 8) & 0xFF]; - vram[(tile * 8) + 2] = m2_bits_to_nybbles_fast[(first_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 3] = m2_bits_to_nybbles_fast[(first_half >> 0x18) & 0xFF]; - vram[(tile * 8) + 4] = m2_bits_to_nybbles_fast[(second_half >> 0) & 0xFF]; - vram[(tile * 8) + 5] = m2_bits_to_nybbles_fast[(second_half >> 8) & 0xFF]; - vram[(tile * 8) + 6] = m2_bits_to_nybbles_fast[(second_half >> 0x10) & 0xFF]; - vram[(tile * 8) + 7] = m2_bits_to_nybbles_fast[(second_half >> 0x18) & 0xFF]; + //Using pointers + a way to keep track of subsequent tiles saves 50k cycles on average + //m2_coord_table_fast_progression has the tile number and the number of tiles used without interruction after it in a single short + tile = m2_coord_table_fast_progression[i]; + int remainingTiles = tile >> 0xB; + tile = (tile & 0x7FF) + (*tile_offset); + topTilePointer = &vram[(tile * 8)]; + bottomTilePointer = topTilePointer + (0x20 * 8); + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + bottomBufferValues += 0x40; + } + i++; + unsigned int first_half = *(topBufferValues++); + unsigned int second_half = *(topBufferValues++); + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + first_half = *(bottomBufferValues++); + //second_half = *(bottomBufferValues++); + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + //Since those are unused + bottomBufferValues++; + bottomTilePointer += 4; + /* The game doesn't use these + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + */ + + while(remainingTiles > 0 && i < totalTiles) + { + if(i == nextValue) + { + nextValue += 0x20; + topBufferValues += 0x40; + bottomBufferValues += 0x40; + } + i++; + first_half = *(topBufferValues++); + second_half = *(topBufferValues++); + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(topTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + first_half = *(bottomBufferValues++); + //second_half = *(bottomBufferValues++); + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(first_half >> 0x18) & 0xFF]; + //Since those are unused + bottomBufferValues++; + bottomTilePointer += 4; + /* The game doesn't use these + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 8) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x10) & 0xFF]; + *(bottomTilePointer++) = bits_to_nybbles_pointer[(second_half >> 0x18) & 0xFF]; + */ + remainingTiles--; + } } } diff --git a/src/c/vwf.h b/src/c/vwf.h index 4996f4d..84cfd31 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -39,6 +39,7 @@ int count_pixels_to_tiles(byte *str, int length, int startingPos); int count_pixels_to_tiles_normal_string(byte *str, int startingPos); int expand_bit_depth(byte row, byte foreground); byte reduce_bit_depth(int row, int foregroundRow); +void reduce_bit_depth_sp(int* TileRows, int* bufferValues); byte print_character(byte chr, int x, int y); byte print_character_formatted(byte chr, int x, int y, int font, int foreground); byte print_character_to_window(byte chr, WINDOW* window); @@ -124,11 +125,13 @@ void load_pixels_overworld_buffer(); void store_pixels_overworld_buffer(int totalYs); void store_pixels_overworld_buffer_totalTiles(int totalTiles); +extern unsigned short m2_coord_table_fast_progression[]; extern unsigned short m2_coord_table[]; extern byte m2_ness_name[]; extern int m2_bits_to_nybbles[]; extern int m2_bits_to_nybbles_fast[]; extern byte m2_nybbles_to_bits[]; +extern byte optimized_byte_4bpp_to_1bpp_table[]; extern byte *m2_font_table[]; extern byte m2_font_widths[]; extern byte m2_font_heights[]; diff --git a/src/data/m2-coord-table-fast-progression.bin b/src/data/m2-coord-table-fast-progression.bin new file mode 100644 index 0000000..c100d2c Binary files /dev/null and b/src/data/m2-coord-table-fast-progression.bin differ diff --git a/src/data/optimized-byte-4bpp-to-1bpp-table.bin b/src/data/optimized-byte-4bpp-to-1bpp-table.bin new file mode 100644 index 0000000..9142c49 Binary files /dev/null and b/src/data/optimized-byte-4bpp-to-1bpp-table.bin differ diff --git a/src/m2-hack.asm b/src/m2-hack.asm index 3811845..4305bee 100644 --- a/src/m2-hack.asm +++ b/src/m2-hack.asm @@ -1693,6 +1693,10 @@ m2_font_relocate: m2_coord_table: .incbin "data/m2-coord-table.bin" +// Co-ordinate table, version which has 5 bits used for how many consecutive tiles there are after each tile +m2_coord_table_fast_progression: +.incbin "data/m2-coord-table-fast-progression.bin" + // EB fonts m2_font_table: dw m2_font_main @@ -1779,6 +1783,9 @@ flyovertextLater: m2_coord_table_file: .incbin "data/m2-coord-table-file-select.bin" +optimized_byte_4bpp_to_1bpp_table: +.incbin "data/optimized-byte-4bpp-to-1bpp-table.bin" + //============================================================================== // Existing subroutines/data diff --git a/working/m12-asmrefs.json b/working/m12-asmrefs.json index 79cd399..9f6ffc0 100644 --- a/working/m12-asmrefs.json +++ b/working/m12-asmrefs.json @@ -1828,5 +1828,47 @@ "PointerLocation": 658252, "OldPointer": 533006, "Label": "L32003" + }, + { + "Index": 305, + "PointerLocation": 616180, + "OldPointer": 279156, + "Label": "L314" + }, + { + "Index": 306, + "PointerLocation": 616184, + "OldPointer": 441774, + "Label": "L1031" + }, + { + "Index": 307, + "PointerLocation": 616220, + "OldPointer": 324778, + "Label": "L610" + }, + { + "Index": 308, + "PointerLocation": 616240, + "OldPointer": 325844, + "Label": "L615" + }, + { + "Index": 309, + "PointerLocation": 616260, + "OldPointer": 326292, + "Label": "L616" + }, + { + "Index": 310, + "PointerLocation": 197030, + "OldPointer": 471486, + "Label": "L32000" + }, + { + "Index": 311, + "PointerLocation": 616200, + "OldPointer": 323841, + "Label": "L603" } ] \ No newline at end of file diff --git a/working/m12-strings-english.txt b/working/m12-strings-english.txt index 457c4c8..15f9899 100644 --- a/working/m12-strings-english.txt +++ b/working/m12-strings-english.txt @@ -4960,7 +4960,7 @@ ^L5603^[B2 FF 02 00 CC 00][1B FF 0F 00][C3 FF 01 01 02 00][D8 FF 01 00 00 00][C3 FF 03 01 02 00][D8 FF 03 00 00 00][1B FF 2D 00][6B FF 03 00][B5 FF 02 00][FC FF 27 00][1B FF 01 00][A0 FF D0 07 8E 00 01 00][9E FF][AA FF D0 07][CB FF 01 00 06 00][CB FF 03 00 06 00][1B FF B4 00]@.....[1D FF][C6 FF][1B FF 3C 00][CC FF 01 00 01 00][CC FF 03 00 01 00][1B FF B4 00][A9 FF D0 07][9E FF][FC FF 28 00][1B FF 01 00]@Oooh... I was a little dizzy,[1B FF 0F 00] but[01 FF] now I'm okay.[02 FF]@...to get to Summers... we[01 FF] need to go back to Threed.[02 FF]@Yep, somehow I know that's[01 FF] where we must go...[1D FF][C6 FF][09 FF 2F 00][08 FF 30 00][08 FF 05 03][08 FF 8F 00][86 FF _L3558_][08 FF 18 02][00 FF] ^L5604^[09 FF 02 00][A6 FF 36 00 C4 01][A6 FF 37 00 C5 01][A6 FF 39 00 C6 01][A6 FF 38 00 C7 01][A6 FF 3A 00 C8 01]@Wow![1B FF 14 00] You guys did a lot while I[01 FF] was in the bathroom! Ha ha ha[01 FF] ha...[02 FF]@You want to get to Threed as[01 FF] soon as possible?[02 FF]@We can take you to Threed in[01 FF] our tour bus.[02 FF]@I'll get the bus and wait for you[01 FF] just outside the building...[02 FF][C6 FF][08 FF 3D 01][09 FF 3E 01][08 FF 02 00][9E FF][9D FF 01 33 _L4162_][00 FF] ^L5605^[09 FF 18 02][9D FF 01 04 _L5606_][08 FF 0B 00][00 FF] -^L5606^[86 FF _L3558_]^L9001^[FC FF 05 00][B0 FF C0 03 CB 00][1B FF 3C 00][B3 FF C0 03][A1 FF C0 03 C9 01][9E FF][A4 FF C0 03][C3 FF 01 02 C0 03][D8 FF 01 00 00 00][C3 FF 02 02 C0 03][D8 FF 02 00 00 00][C3 FF 03 02 C0 03][D8 FF 03 00 00 00]@Heh heh heh...[01 FF] There's no need to wait...[02 FF][C6 FF][A0 FF D0 07 CB 01 01 00][C9 FF D0 07][EB FF FF 00][A3 FF C0 03][9E FF][1B FF 3C 00][A5 FF D0 07 06 00][CA FF][A0 FF D3 07 04 03 01 00][A0 FF D0 07 CD 01 01 00][C9 FF D0 07][EB FF FF 00][9E FF][CB FF FF 00 06 00][09 FF 18 02][08 FF 17 02][C5 FF][EA FF FF 00][09 FF 3D 01][A1 FF C0 03 CE 01][9E FF]@All right... on to Threed![02 FF][C6 FF][A1 FF E2 03 CF 01][1B FF 3C 00][E6 FF E2 03][EB FF FF 00][6E FF 01 00][00 FF] +^L5606^[86 FF _L3558_]^L9001^[FC FF 05 00][B0 FF C0 03 CB 00][1B FF 3C 00][B3 FF C0 03][A1 FF C0 03 C9 01][9E FF][A4 FF C0 03][C3 FF 01 02 C0 03][D8 FF 01 00 00 00][C3 FF 02 02 C0 03][D8 FF 02 00 00 00][C3 FF 03 02 C0 03][D8 FF 03 00 00 00]@Heh heh heh...[01 FF] There's no need to wait...[02 FF][C6 FF][A0 FF D0 07 CB 01 01 00][C9 FF D0 07][EB FF FF 00][A3 FF C0 03][9E FF][1B FF 3C 00][A5 FF D0 07 06 00][CA FF]^L32000^[A0 FF D3 07 04 03 01 00][A0 FF D0 07 CD 01 01 00][C9 FF D0 07][EB FF FF 00][9E FF][CB FF FF 00 06 00][09 FF 18 02][08 FF 17 02][C5 FF][EA FF FF 00][09 FF 3D 01][A1 FF C0 03 CE 01][9E FF]@All right... on to Threed![02 FF][C6 FF][A1 FF E2 03 CF 01][1B FF 3C 00][E6 FF E2 03][EB FF FF 00][6E FF 01 00][00 FF] ^L5607^[9D FF 01 28 _L4238_][00 FF] ^L5608^[A2 FF _L5609_][00 FF] ^L5609^[EA FF FF 00][FC FF 05 00][8D FF 01 00][A4 FF EC 01][A4 FF ED 01][A4 FF EE 01][A4 FF EF 01][A4 FF F0 01][1B FF 1E 00][A3 FF EC 01][A3 FF ED 01][A3 FF EE 01][A3 FF EF 01][A3 FF F0 01][1B FF 0A 00][A4 FF EC 01][A4 FF ED 01][A4 FF EE 01][A4 FF EF 01][A4 FF F0 01][B2 FF 00 00 CC 00][1B FF 3C 00][B5 FF 00 00][A3 FF ED 01][A3 FF EE 01][A3 FF EF 01][A3 FF F0 01][6B FF 02 00][1B FF 0A 00][C4 FF 00 C1][A0 FF D0 07 8B 00 01 00][9E FF][1B FF 78 00]@(Oh,[1B FF 05 00] oh...[1B FF 14 00] you're losing[01 FF] consciousness...[02 FF]@What could be the fate of[01 FF] [0D FF] and his friend?)[1D FF][C6 FF][1B FF 01 00][86 FF _L2866_][86 FF _L2200_][08 FF 0B 00][CB FF FF 00 06 00][14 FF 10 00][A0 FF 25 01 8C 00 FF 00][A0 FF 26 01 8D 00 FF 00][EA FF FF 00][1B FF F0 00][A5 FF 25 01 06 00][CC FF 01 00 01 00][D8 FF 01 00 05 00][1B FF 1E 00][C3 FF 01 03 26 01][D8 FF 01 00 00 00][1B FF 14 00][A5 FF 26 01 06 00][A0 FF 01 00 0C 00 01 00][DA FF 01 00 07 00][1B FF 3C 00][A6 FF 01 00 15 00][9E FF][A5 FF 01 00 06 00][CC FF FF 00 01 00][EB FF FF 00][D8 FF 01 00 05 00][00 FF] diff --git a/working/m12-strings.txt b/working/m12-strings.txt index 37dd24d..2ff0032 100644 --- a/working/m12-strings.txt +++ b/working/m12-strings.txt @@ -3601,7 +3601,7 @@ ^L5603^[B2 FF 02 00 CC 00][1B FF 0F 00][C3 FF 01 01 02 00][D8 FF 01 00 00 00][C3 FF 03 01 02 00][D8 FF 03 00 00 00][1B FF 2D 00][6B FF 03 00][B5 FF 02 00][FC FF 27 00][1B FF 01 00][A0 FF D0 07 8E 00 01 00][9E FF][AA FF D0 07][CB FF 01 00 06 00][CB FF 03 00 06 00][1B FF B4 00]◆¨¨¨。[1D FF][C6 FF][1B FF 3C 00][CC FF 01 00 01 00][CC FF 03 00 01 00][1B FF B4 00][A9 FF D0 07][9E FF][FC FF 28 00][1B FF 01 00]◆ちょっと めまいがしただけよ。[01 FF] だいじょうぶ。[02 FF]◆¨¨サマ-ズに[01 FF] いくためには¨¨。[02 FF]◆スリ-クに[01 FF] もどるひつようがあるわ。[02 FF]◆いま つよく[01 FF] それを かんじたの。[1D FF][C6 FF][09 FF 2F 00][08 FF 30 00][08 FF 05 03][08 FF 8F 00][86 FF _L3558_][08 FF 18 02][00 FF] ^L5604^[09 FF 02 00][A6 FF 36 00 C4 01][A6 FF 37 00 C5 01][A6 FF 39 00 C6 01][A6 FF 38 00 C7 01][A6 FF 3A 00 C8 01][1B FF 1E 00]◆な-んだ[01 FF] トイレにいってるあいだに[01 FF] だいかつやく しやがって![02 FF]◆ハハハ[02 FF]◆なになに? [0E FF]ちゃん[01 FF] いまから スリ-クに[01 FF] いきたいって?[02 FF]◆OK![02 FF]◆おれたちの トラベリング・バスで[01 FF] スリ-クまで おくるぜ。[02 FF]◆ひとあしさきに[01 FF] くるまを まわしとく。[1B FF 14 00][01 FF] ビルの そとで まってるぜ![02 FF][C6 FF][08 FF 3D 01][09 FF 3E 01][08 FF 02 00][9E FF][9D FF 01 33 _L4162_][00 FF] ^L694^◆オ-ケ-![01 FF] ノリノリで バスにのれ![02 FF][C6 FF][00 FF] -^L5606^[86 FF _L3558_]^L9001^[FC FF 05 00][B0 FF C0 03 CB 00][1B FF 3C 00][B3 FF C0 03][A1 FF C0 03 C9 01][9E FF][A4 FF C0 03][C3 FF 01 02 C0 03][D8 FF 01 00 00 00][C3 FF 02 02 C0 03][D8 FF 02 00 00 00][C3 FF 03 02 C0 03][D8 FF 03 00 00 00]◆カッカッカッ[01 FF] えんりょは いらんわい![02 FF][C6 FF][A0 FF D0 07 CB 01 01 00][C9 FF D0 07][EB FF FF 00][A3 FF C0 03][9E FF][1B FF 3C 00][A5 FF D0 07 06 00][CA FF][A0 FF D3 07 04 03 01 00][A0 FF D0 07 CD 01 01 00][C9 FF D0 07][EB FF FF 00][9E FF][CB FF FF 00 06 00][09 FF 18 02][08 FF 17 02][C5 FF][EA FF FF 00][09 FF 3D 01][A1 FF C0 03 CE 01][9E FF]◆さあ スリ-クめざして[01 FF] しゅっぱつだ![02 FF][C6 FF][A1 FF E2 03 CF 01][1B FF 3C 00][E6 FF E2 03][EB FF FF 00][6E FF 01 00][00 FF] +^L5606^[86 FF _L3558_]^L9001^[FC FF 05 00][B0 FF C0 03 CB 00][1B FF 3C 00][B3 FF C0 03][A1 FF C0 03 C9 01][9E FF][A4 FF C0 03][C3 FF 01 02 C0 03][D8 FF 01 00 00 00][C3 FF 02 02 C0 03][D8 FF 02 00 00 00][C3 FF 03 02 C0 03][D8 FF 03 00 00 00]◆カッカッカッ[01 FF] えんりょは いらんわい![02 FF][C6 FF][A0 FF D0 07 CB 01 01 00][C9 FF D0 07][EB FF FF 00][A3 FF C0 03][9E FF][1B FF 3C 00][A5 FF D0 07 06 00][CA FF]^L32000^[A0 FF D3 07 04 03 01 00][A0 FF D0 07 CD 01 01 00][C9 FF D0 07][EB FF FF 00][9E FF][CB FF FF 00 06 00][09 FF 18 02][08 FF 17 02][C5 FF][EA FF FF 00][09 FF 3D 01][A1 FF C0 03 CE 01][9E FF]◆さあ スリ-クめざして[01 FF] しゅっぱつだ![02 FF][C6 FF][A1 FF E2 03 CF 01][1B FF 3C 00][E6 FF E2 03][EB FF FF 00][6E FF 01 00][00 FF] ^L1648^[CA FF][14 FF 2D 00][A0 FF 62 01 D0 01 FF 00][C9 FF 62 01][00 FF] ^L1636^[CA FF][14 FF 2E 00][A0 FF 62 01 D1 01 FF 00][C9 FF 62 01][00 FF] ^L1637^[CA FF][14 FF 2F 00][A0 FF 62 01 D2 01 FF 00][C9 FF 62 01][00 FF]