diff --git a/src/ff8.h b/src/ff8.h index a6c93c41..4035ad54 100644 --- a/src/ff8.h +++ b/src/ff8.h @@ -1091,6 +1091,14 @@ struct ff8_externals uint32_t ssigpu_init; uint32_t *d3dcaps; uint32_t sub_53BB90; + uint32_t worldmap_fog_filter_polygons_in_block_1; + uint32_t worldmap_polygon_condition_2045C8C; + uint32_t worldmap_has_polygon_condition_2045C90; + uint32_t worldmap_sub_45DF20; + uint32_t sub_45E3A0; + uint32_t worldmap_fog_filter_polygons_in_block_2; + uint32_t sub_461E00; + uint32_t dword_1CA8848; uint32_t sub_53E2A0; uint32_t sub_53E6B0; uint32_t sub_4023D0; @@ -1171,6 +1179,7 @@ struct ff8_externals uint32_t *ssigpu_callbacks_2; uint32_t sub_462AD0; uint32_t sub_462DF0; + uint32_t sub_461220; uint32_t ssigpu_tx_select_2_sub_465CE0; int (*sub_464F70)(struc_50 *, texture_page *, int, int, int, int, int, int, int, uint8_t *); void(*read_vram_1)(uint8_t *, int, uint8_t *, int, signed int, int, int); diff --git a/src/ff8/uv_patch.cpp b/src/ff8/uv_patch.cpp index 7735a2f8..9971a06d 100644 --- a/src/ff8/uv_patch.cpp +++ b/src/ff8/uv_patch.cpp @@ -56,65 +56,61 @@ struct SsigpuExecutionInstruction { int current_polygon = -1; void *current_polygon_condition_old = nullptr; -bool old_dword_2045968_value = false; +bool old_dword_2045C90_value = false; uint8_t *current_block_data_start = nullptr; float *maybe_hundred_bak = nullptr; -void worldmap_fog_common_leave() +void worldmap_fog_filter_polygons_in_block_leave() { - void **current_polygon_condition_dword_2045964 = (void **)0x2045964; - bool *dword_2045968 = (bool *)0x2045968; - - *dword_2045968 = old_dword_2045968_value; - *current_polygon_condition_dword_2045964 = current_polygon_condition_old; + *(bool *)ff8_externals.worldmap_has_polygon_condition_2045C90 = old_dword_2045C90_value; + *(void **)ff8_externals.worldmap_polygon_condition_2045C8C = current_polygon_condition_old; } -void worldmap_fog_sub_551AC0(uint8_t *block, int a2, void *out) +void worldmap_fog_filter_polygons_in_block_1(uint8_t *block, int a2, void *out) { current_block_data_start = block; - ((void(*)(uint8_t*,int,void*))0x551AC0)(block, a2, out); + ((void(*)(uint8_t*,int,void*))ff8_externals.worldmap_fog_filter_polygons_in_block_1)(block, a2, out); - worldmap_fog_common_leave(); + worldmap_fog_filter_polygons_in_block_leave(); } -void worldmap_fog_sub_552480(uint8_t *block, int a2, void *out) +void worldmap_fog_filter_polygons_in_block_2(uint8_t *block, int a2, void *out) { current_block_data_start = block; - ((void(*)(uint8_t*,int,void*))0x552480)(block, a2, out); + ((void(*)(uint8_t*,int,void*))ff8_externals.worldmap_fog_filter_polygons_in_block_2)(block, a2, out); - worldmap_fog_common_leave(); + worldmap_fog_filter_polygons_in_block_leave(); } bool current_polygon_condition(int polygon_id) { current_polygon = polygon_id; - if (!old_dword_2045968_value) { + if (!old_dword_2045C90_value) { return true; } return ((bool(*)(int))current_polygon_condition_old)(polygon_id); } -void sub_45DF10(int a1, int a2, int a3) +void sub_45DF20(int a1, int a2, int a3) { - void **current_polygon_condition_dword_2045964 = (void **)0x2045964; - bool *dword_2045968 = (bool *)0x2045968; + void **current_polygon_condition_dword_2045964 = (void **)ff8_externals.worldmap_polygon_condition_2045C8C; - old_dword_2045968_value = *dword_2045968; + old_dword_2045C90_value = *(bool *)ff8_externals.worldmap_has_polygon_condition_2045C90; - if (!old_dword_2045968_value) { - *dword_2045968 = true; + if (!old_dword_2045C90_value) { + *(bool *)ff8_externals.worldmap_has_polygon_condition_2045C90 = true; current_polygon_condition_old = *current_polygon_condition_dword_2045964; *current_polygon_condition_dword_2045964 = current_polygon_condition; } - ((void(*)(int,int,int))0x45DF10)(a1, a2, a3); + ((void(*)(int,int,int))ff8_externals.worldmap_sub_45DF20)(a1, a2, a3); } -void enrich_tex_coords_sub_45E390f(SsigpuExecutionInstruction *a1) +void enrich_tex_coords_sub_45E3A0(SsigpuExecutionInstruction *a1) { MapBlockPolygon *polygon = (MapBlockPolygon *)(current_block_data_start + 4 + current_polygon * sizeof(MapBlockPolygon)); // Save the last bit of texture coordinates in field_26 @@ -122,18 +118,21 @@ void enrich_tex_coords_sub_45E390f(SsigpuExecutionInstruction *a1) | ((polygon->pos[1].x & 1) << 2) | ((polygon->pos[1].y & 1) << 3) | ((polygon->pos[2].x & 1) << 4) | ((polygon->pos[2].y & 1) << 5); - ((void(*)(SsigpuExecutionInstruction*))0x45E390)(a1); + ((void(*)(SsigpuExecutionInstruction*))ff8_externals.sub_45E3A0)(a1); } -void ssigpu_callback_sub_461DF0(SsigpuExecutionInstruction *a1) +void ssigpu_callback_sub_461E00(SsigpuExecutionInstruction *a1) { - uint8_t lost_bits = a1->field_26; + uint8_t lost_bits = a1->field_26; + + ffnx_info("%s\n", __func__); - ((void(*)(SsigpuExecutionInstruction*))0x461DF0)(a1); + ((void(*)(SsigpuExecutionInstruction*))ff8_externals.sub_461E00)(a1); - int dword_1CA8520 = *(int *)0x1CA8520; + ffnx_info("%s2\n", __func__); - if (!dword_1CA8520 && maybe_hundred_bak != nullptr) { + if (!(*(int *)ff8_externals.dword_1CA8848) && maybe_hundred_bak != nullptr) { + // Not 512 to avoid space between textures maybe_hundred_bak[6] = double(uint32_t(a1->tex_coord_a.x) * 2 + ((lost_bits >> 0) & 1)) / 511.999; maybe_hundred_bak[7] = double(uint32_t(a1->tex_coord_a.y) * 2 + ((lost_bits >> 1) & 1)) / 511.999; maybe_hundred_bak[14] = double(uint32_t(a1->tex_coord_b.x) * 2 + ((lost_bits >> 2) & 1)) / 511.999; @@ -143,25 +142,38 @@ void ssigpu_callback_sub_461DF0(SsigpuExecutionInstruction *a1) maybe_hundred_bak = nullptr; } + + ffnx_info("%s3\n", __func__); } -void ssigpu_sub_461210(float *maybe_hundred) +void ssigpu_sub_461220(float *maybe_hundred) { maybe_hundred_bak = maybe_hundred; - ((void(*)(float*))0x461210)(maybe_hundred); + ((void(*)(float*))ff8_externals.sub_461220)(maybe_hundred); } void uv_patch_init() { - replace_call(0x53B97B, worldmap_fog_sub_551AC0); - replace_call(0x53C051, worldmap_fog_sub_551AC0); - replace_call(0x53B990, worldmap_fog_sub_552480); - replace_call(0x53C066, worldmap_fog_sub_552480); - replace_call(0x5526C1, sub_45DF10); - replace_call(0x552B4D, enrich_tex_coords_sub_45E390f); - void **ssigpu_callbacks_dword_B7CF08 = (void **)0xB7CF08; - *(ssigpu_callbacks_dword_B7CF08 + 52) = ssigpu_callback_sub_461DF0; - *(ssigpu_callbacks_dword_B7CF08 + 53) = ssigpu_callback_sub_461DF0; - replace_call(0x461E40, ssigpu_sub_461210); + /* We hook a lot of stuff here to bring back full precision in texture UVs + * - We need the UVs directly from the game data. To obtain this, + * we get the current block data and the current polygon from the game. + * - Then we put this information into the SSIGPU instruction, the game will + * only stores the UVs divided by 2, so we need to remember the forgotten bits at least. + * - And when the game uses the UVs from the SSIGPU instruction, we alter + * the computation of U and V using the forgotten bits. + */ + bool isUs = version == VERSION_FF8_12_US || version == VERSION_FF8_12_US_NV || version == VERSION_FF8_12_US_EIDOS || version == VERSION_FF8_12_US_EIDOS_NV; + + // Worldmap with Fog enabled + replace_call(ff8_externals.sub_53BB90 + (isUs ? 0x42D : 0x43B), worldmap_fog_filter_polygons_in_block_1); + replace_call(ff8_externals.sub_53BB90 + (isUs ? 0xADD : 0xB11), worldmap_fog_filter_polygons_in_block_1); + replace_call(ff8_externals.sub_53BB90 + (isUs ? 0x442 : 0x450), worldmap_fog_filter_polygons_in_block_2); + replace_call(ff8_externals.sub_53BB90 + (isUs ? 0xAFE : 0xB26), worldmap_fog_filter_polygons_in_block_2); + replace_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1 + (isUs ? 0x239 : 0x202), sub_45DF20); + replace_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1 + (isUs ? 0x5C8 : 0x5DC), enrich_tex_coords_sub_45E3A0); + replace_call(ff8_externals.worldmap_fog_filter_polygons_in_block_2 + (isUs ? 0x281 : 0x241), sub_45DF20); + replace_call(ff8_externals.worldmap_fog_filter_polygons_in_block_2 + (isUs ? 0x698 : 0x6CD), enrich_tex_coords_sub_45E3A0); + replace_call(ff8_externals.sub_461E00 + 0x50, ssigpu_sub_461220); + ff8_externals.ssigpu_callbacks_1[52] = uint32_t(ssigpu_callback_sub_461E00); } diff --git a/src/ff8_data.cpp b/src/ff8_data.cpp index 0008045f..9088485d 100644 --- a/src/ff8_data.cpp +++ b/src/ff8_data.cpp @@ -292,6 +292,10 @@ void ff8_find_externals() ff8_externals.ssigpu_callbacks_1 = (uint32_t *)get_absolute_value(ff8_externals.sub_45D080, 0x21E); ff8_externals.ssigpu_callbacks_2 = (uint32_t *)get_absolute_value(ff8_externals.sub_45D080, 0x122); + ff8_externals.sub_461E00 = ff8_externals.ssigpu_callbacks_1[52]; + ff8_externals.sub_461220 = get_relative_call(ff8_externals.sub_461E00, 0x50); + ff8_externals.dword_1CA8848 = get_absolute_value(ff8_externals.sub_461E00, 0x56); + ffnx_info("%X %X\n", ff8_externals.sub_461E00, ff8_externals.dword_1CA8848); ff8_externals.sub_462AD0 = get_relative_call(ff8_externals.ssigpu_callbacks_1[116], 0x13); ff8_externals.sub_462DF0 = get_relative_call(ff8_externals.sub_462AD0, 0x62); ff8_externals.ssigpu_tx_select_2_sub_465CE0 = get_relative_call(ff8_externals.sub_462DF0, 0x33); @@ -488,6 +492,12 @@ void ff8_find_externals() ff8_externals.sub_53E2A0 = get_relative_call(ff8_externals.sub_53BB90, 0x327); ff8_externals.sub_53E6B0 = get_relative_call(ff8_externals.sub_53E2A0, 0x36B); ff8_externals.sub_4023D0 = get_relative_call(ff8_externals.sub_53BB90, 0xAB1); + ff8_externals.worldmap_fog_filter_polygons_in_block_1 = get_relative_call(ff8_externals.sub_53BB90, 0x42D); + ff8_externals.worldmap_has_polygon_condition_2045C90 = get_absolute_value(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x29); + ff8_externals.worldmap_polygon_condition_2045C8C = get_absolute_value(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x59); + ff8_externals.worldmap_sub_45DF20 = get_relative_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x1FC); + ff8_externals.sub_45E3A0 = get_relative_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x4A4); + ff8_externals.worldmap_fog_filter_polygons_in_block_2 = get_relative_call(ff8_externals.sub_53BB90, 0x442); ff8_externals.sub_53C750 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, 0x2DB); ff8_externals.sub_54FDA0 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, 0x375); ff8_externals.sub_54D7E0 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, 0x3C2); @@ -526,6 +536,12 @@ void ff8_find_externals() ff8_externals.sub_53E2A0 = get_relative_call(ff8_externals.sub_53BB90, 0x336); ff8_externals.sub_53E6B0 = get_relative_call(ff8_externals.sub_53E2A0, 0x39A); ff8_externals.sub_4023D0 = get_relative_call(ff8_externals.sub_53BB90, 0xAE5); + ff8_externals.worldmap_fog_filter_polygons_in_block_1 = get_relative_call(ff8_externals.sub_53BB90, 0x43B); + ff8_externals.worldmap_has_polygon_condition_2045C90 = get_absolute_value(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x51); + ff8_externals.worldmap_polygon_condition_2045C8C = get_absolute_value(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x5D); + ff8_externals.worldmap_sub_45DF20 = get_relative_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x202); + ff8_externals.sub_45E3A0 = get_relative_call(ff8_externals.worldmap_fog_filter_polygons_in_block_1, 0x4B8); + ff8_externals.worldmap_fog_filter_polygons_in_block_2 = get_relative_call(ff8_externals.sub_53BB90, 0x450); if (JP_VERSION) { ff8_externals.sub_4023D0 = get_relative_call(ff8_externals.sub_4023D0, 0x0);