replace the x64 specific change_map_tile() with a generic c implementation

This commit is contained in:
Sven Balzer 2026-04-02 17:02:16 +02:00
parent 8a5caf5c0d
commit 9dd37f6d40

View File

@ -1230,28 +1230,31 @@ static Uint32 find_matching_tile(Uint32 corner_info) {
} }
static void change_map_tile(Sint32 pos_x, Sint32 pos_y, TileKind kind) { static void change_map_tile(Sint32 pos_x, Sint32 pos_y, TileKind kind) {
__m128i corner_infos = _mm_setr_epi32(get_corner_info(pos_x, pos_y + 1), get_corner_info(pos_x + 1, pos_y + 1), get_corner_info(pos_x + 1, pos_y), get_corner_info(pos_x, pos_y)); const Uint32 INFO_NONE = ((TILEKIND_NONE << 24) | (TILEKIND_NONE << 16) | (TILEKIND_NONE << 8) | TILEKIND_NONE);
__m128i none_mask = _mm_cmpeq_epi8(corner_infos, _mm_set1_epi8(TILEKIND_NONE)); const Uint32 INFO_ERROR = ((TILEKIND_ERROR << 24) | (TILEKIND_ERROR << 16) | (TILEKIND_ERROR << 8) | TILEKIND_ERROR);
__m128i error_mask = _mm_cmpeq_epi8(corner_infos, _mm_set1_epi8(TILEKIND_ERROR)); const Uint32 INFO_MASKS[4] = { 0x0000ff00, 0x000000ff, 0xff000000, 0x00ff0000 };
__m128i kind_mask = _mm_setr_epi32(0x0000ff00, 0x000000ff, 0xff000000, 0x00ff0000);
__m128i replace_mask = _mm_or_si128(_mm_or_si128(none_mask, kind_mask), error_mask);
corner_infos = _mm_andnot_si128(replace_mask, corner_infos);
corner_infos = _mm_or_si128(corner_infos, _mm_and_si128(replace_mask, _mm_set1_epi8(kind)));
Uint32 corner_infos_u32[4]; Uint32 corner_infos[4] = { get_corner_info(pos_x + 0, pos_y + 1), get_corner_info(pos_x + 1, pos_y + 1), get_corner_info(pos_x + 1, pos_y + 0), get_corner_info(pos_x + 0, pos_y + 0) };
_mm_storeu_si128((__m128i *)&corner_infos_u32, corner_infos);
if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height) for (int i = 0; i < 4; i++) {
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[0]); Uint32 replace_mask = INFO_MASKS[i];
if ((corner_infos[i] == INFO_NONE) | (corner_infos[i] == INFO_ERROR))
replace_mask = 0xffffffff;
corner_infos[i] = corner_infos[i] ^ ((corner_infos[i] ^ ((kind << 24) | (kind << 16) | (kind << 8) | kind)) & replace_mask);
}
if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height)
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos[0]);
if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height) if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height)
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[1]); current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos[1]);
if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height) if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height)
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[2]); current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos[2]);
if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height) if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height)
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[3]); current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos[3]);
update_buffer(current_map.gpu_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles); update_buffer(current_map.gpu_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles);
} }