remove rotation from world tiles and instead apply it on load into atlas
This commit is contained in:
parent
59cb6fb6c1
commit
7cb6dbc3e6
Binary file not shown.
258
src/main.cpp
258
src/main.cpp
@ -293,44 +293,94 @@ typedef enum : Uint8 {
|
|||||||
TILEKIND_WATER = 4,
|
TILEKIND_WATER = 4,
|
||||||
} TileKind;
|
} TileKind;
|
||||||
|
|
||||||
#define TILE_CORNER_INFO(top_left, top_right, bottom_right, bottom_left) (((TILEKIND_##top_left) << 24) | ((TILEKIND_##top_right) << 16) | ((TILEKIND_##bottom_right) << 8) | (TILEKIND_##bottom_left))
|
#define TILE_CORNER_INFO(rotation, top_left, top_right, bottom_right, bottom_left) (rotation), std::rotl((Uint32)(((TILEKIND_##top_left) << 24) | ((TILEKIND_##top_right) << 16) | ((TILEKIND_##bottom_right) << 8) | (TILEKIND_##bottom_left)), (rotation) * 8)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Uint16 type;
|
Uint16 serialization_id;
|
||||||
const char *asset_path;
|
const char *asset_path;
|
||||||
|
|
||||||
|
Uint8 rotation;
|
||||||
Uint32 corner_info;
|
Uint32 corner_info;
|
||||||
} TileInfo;
|
} TileInfo;
|
||||||
|
|
||||||
|
// TILE_CORNER_INFO ORDER:
|
||||||
|
// 0 1 2 3
|
||||||
|
// +---+---+ +---+---+ +---+---+ +---+---+
|
||||||
|
// | 1 | 2 | | 2 | 3 | | 3 | 4 | | 4 | 1 |
|
||||||
|
// +---+---+ +---+---+ +---+---+ +---+---+
|
||||||
|
// | 4 | 3 | | 1 | 4 | | 2 | 1 | | 3 | 2 |
|
||||||
|
// +---+---+ +---+---+ +---+---+ +---+---+
|
||||||
|
|
||||||
static TileInfo tile_infos[] = {
|
static TileInfo tile_infos[] = {
|
||||||
{ 0x0001, "tiles/error.png", TILE_CORNER_INFO(ERROR, ERROR, ERROR, ERROR) },
|
{ 1, "tiles/error.png", TILE_CORNER_INFO(0, ERROR, ERROR, ERROR, ERROR) },
|
||||||
{ 0x0000, "tiles/empty.png", TILE_CORNER_INFO(NONE, NONE, NONE, NONE ) },
|
{ 0, "tiles/empty.png", TILE_CORNER_INFO(0, NONE, NONE, NONE, NONE ) },
|
||||||
{ 0x0102, "tiles/grass_3.png", TILE_CORNER_INFO(GRASS, GRASS, GRASS, GRASS) },
|
|
||||||
{ 0x0100, "tiles/grass_1.png", TILE_CORNER_INFO(GRASS, GRASS, GRASS, GRASS) },
|
// GRASS
|
||||||
{ 0x0101, "tiles/grass_2.png", TILE_CORNER_INFO(GRASS, GRASS, GRASS, GRASS) },
|
{ 2, "tiles/grass_3.png", TILE_CORNER_INFO(0, GRASS, GRASS, GRASS, GRASS) },
|
||||||
{ 0x0103, "tiles/grass_4.png", TILE_CORNER_INFO(GRASS, GRASS, GRASS, GRASS) },
|
{ 3, "tiles/grass_1.png", TILE_CORNER_INFO(0, GRASS, GRASS, GRASS, GRASS) },
|
||||||
{ 0x0202, "tiles/dirt_3.png", TILE_CORNER_INFO(DIRT, DIRT, DIRT, DIRT ) },
|
{ 4, "tiles/grass_2.png", TILE_CORNER_INFO(0, GRASS, GRASS, GRASS, GRASS) },
|
||||||
{ 0x0200, "tiles/dirt_1.png", TILE_CORNER_INFO(DIRT, DIRT, DIRT, DIRT ) },
|
{ 5, "tiles/grass_4.png", TILE_CORNER_INFO(0, GRASS, GRASS, GRASS, GRASS) },
|
||||||
{ 0x0201, "tiles/dirt_2.png", TILE_CORNER_INFO(DIRT, DIRT, DIRT, DIRT ) },
|
|
||||||
{ 0x0300, "tiles/water_1.png", TILE_CORNER_INFO(WATER, WATER, WATER, WATER) },
|
// DIRT
|
||||||
{ 0x0301, "tiles/water_2.png", TILE_CORNER_INFO(WATER, WATER, WATER, WATER) },
|
{ 6, "tiles/dirt_3.png", TILE_CORNER_INFO(0, DIRT, DIRT, DIRT, DIRT ) },
|
||||||
{ 0x0400, "tiles/grass_dirt_1.png", TILE_CORNER_INFO(DIRT, DIRT, GRASS, GRASS) },
|
{ 7, "tiles/dirt_1.png", TILE_CORNER_INFO(0, DIRT, DIRT, DIRT, DIRT ) },
|
||||||
{ 0x0401, "tiles/grass_dirt_2.png", TILE_CORNER_INFO(DIRT, DIRT, GRASS, GRASS) },
|
{ 8, "tiles/dirt_2.png", TILE_CORNER_INFO(0, DIRT, DIRT, DIRT, DIRT ) },
|
||||||
{ 0x0402, "tiles/grass_dirt_3.png", TILE_CORNER_INFO(DIRT, DIRT, GRASS, GRASS) },
|
|
||||||
{ 0x0410, "tiles/grass_dirt_outer_corner_1.png", TILE_CORNER_INFO(DIRT, DIRT, GRASS, DIRT ) },
|
// WATER
|
||||||
{ 0x0411, "tiles/grass_dirt_outer_corner_2.png", TILE_CORNER_INFO(DIRT, DIRT, GRASS, DIRT ) },
|
{ 9, "tiles/water_1.png", TILE_CORNER_INFO(0, WATER, WATER, WATER, WATER) },
|
||||||
{ 0x0420, "tiles/grass_dirt_inner_corner_1.png", TILE_CORNER_INFO(GRASS, DIRT, GRASS, GRASS) },
|
{ 10, "tiles/water_2.png", TILE_CORNER_INFO(0, WATER, WATER, WATER, WATER) },
|
||||||
{ 0x0421, "tiles/grass_dirt_inner_corner_2.png", TILE_CORNER_INFO(GRASS, DIRT, GRASS, GRASS) },
|
|
||||||
{ 0x0422, "tiles/grass_dirt_inner_corner_3.png", TILE_CORNER_INFO(GRASS, DIRT, GRASS, GRASS) },
|
// GRASS / DIRT
|
||||||
{ 0x0423, "tiles/grass_dirt_two_corner.png", TILE_CORNER_INFO(GRASS, DIRT, GRASS, DIRT ) },
|
{ 11, "tiles/grass_dirt_1.png", TILE_CORNER_INFO(0, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 12, "tiles/grass_dirt_1.png", TILE_CORNER_INFO(1, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 13, "tiles/grass_dirt_1.png", TILE_CORNER_INFO(2, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 14, "tiles/grass_dirt_1.png", TILE_CORNER_INFO(3, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 15, "tiles/grass_dirt_2.png", TILE_CORNER_INFO(0, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 16, "tiles/grass_dirt_2.png", TILE_CORNER_INFO(1, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 17, "tiles/grass_dirt_2.png", TILE_CORNER_INFO(2, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 18, "tiles/grass_dirt_2.png", TILE_CORNER_INFO(3, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 19, "tiles/grass_dirt_3.png", TILE_CORNER_INFO(0, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 20, "tiles/grass_dirt_3.png", TILE_CORNER_INFO(1, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 21, "tiles/grass_dirt_3.png", TILE_CORNER_INFO(2, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
{ 22, "tiles/grass_dirt_3.png", TILE_CORNER_INFO(3, DIRT, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 23, "tiles/grass_dirt_outer_corner_1.png", TILE_CORNER_INFO(0, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 24, "tiles/grass_dirt_outer_corner_1.png", TILE_CORNER_INFO(1, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 25, "tiles/grass_dirt_outer_corner_1.png", TILE_CORNER_INFO(2, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 26, "tiles/grass_dirt_outer_corner_1.png", TILE_CORNER_INFO(3, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
|
||||||
|
{ 27, "tiles/grass_dirt_outer_corner_2.png", TILE_CORNER_INFO(0, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 28, "tiles/grass_dirt_outer_corner_2.png", TILE_CORNER_INFO(1, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 29, "tiles/grass_dirt_outer_corner_2.png", TILE_CORNER_INFO(2, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 30, "tiles/grass_dirt_outer_corner_2.png", TILE_CORNER_INFO(3, DIRT, DIRT, GRASS, DIRT ) },
|
||||||
|
|
||||||
|
{ 31, "tiles/grass_dirt_inner_corner_1.png", TILE_CORNER_INFO(0, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 32, "tiles/grass_dirt_inner_corner_1.png", TILE_CORNER_INFO(1, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 33, "tiles/grass_dirt_inner_corner_1.png", TILE_CORNER_INFO(2, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 34, "tiles/grass_dirt_inner_corner_1.png", TILE_CORNER_INFO(3, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 35, "tiles/grass_dirt_inner_corner_2.png", TILE_CORNER_INFO(0, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 36, "tiles/grass_dirt_inner_corner_2.png", TILE_CORNER_INFO(1, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 37, "tiles/grass_dirt_inner_corner_2.png", TILE_CORNER_INFO(2, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 38, "tiles/grass_dirt_inner_corner_2.png", TILE_CORNER_INFO(3, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 39, "tiles/grass_dirt_inner_corner_3.png", TILE_CORNER_INFO(0, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 40, "tiles/grass_dirt_inner_corner_3.png", TILE_CORNER_INFO(1, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 41, "tiles/grass_dirt_inner_corner_3.png", TILE_CORNER_INFO(2, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
{ 42, "tiles/grass_dirt_inner_corner_3.png", TILE_CORNER_INFO(3, GRASS, DIRT, GRASS, GRASS) },
|
||||||
|
|
||||||
|
{ 43, "tiles/grass_dirt_two_corner.png", TILE_CORNER_INFO(0, GRASS, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 44, "tiles/grass_dirt_two_corner.png", TILE_CORNER_INFO(1, GRASS, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 45, "tiles/grass_dirt_two_corner.png", TILE_CORNER_INFO(2, GRASS, DIRT, GRASS, DIRT ) },
|
||||||
|
{ 46, "tiles/grass_dirt_two_corner.png", TILE_CORNER_INFO(3, GRASS, DIRT, GRASS, DIRT ) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static vec4 tile_uvs[SDL_arraysize(tile_infos)];
|
static vec4 tile_uvs[SDL_arraysize(tile_infos)];
|
||||||
|
|
||||||
static Sint32 selected_tile_kind = -1;
|
static Sint32 selected_tile_kind = -1;
|
||||||
|
static Sint32 selected_tile = -1;
|
||||||
static Sint32 selected_tile = -1;
|
|
||||||
static Sint32 selected_rotation = 0;
|
|
||||||
|
|
||||||
static bool dragging_tile_change;
|
static bool dragging_tile_change;
|
||||||
static bool dragging_camera_change;
|
static bool dragging_camera_change;
|
||||||
@ -360,7 +410,7 @@ static WGPUBuffer create_buffer(WGPUBufferUsage usage, Uint32 num_bytes, void *d
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAP_FILE_VERSION (1u)
|
#define MAP_FILE_VERSION (2u)
|
||||||
|
|
||||||
static bool save_map(Map map) {
|
static bool save_map(Map map) {
|
||||||
char path[256] = ASSETS_PATH "maps/";
|
char path[256] = ASSETS_PATH "maps/";
|
||||||
@ -389,11 +439,9 @@ static bool save_map(Map map) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < map.size.x * map.size.y; i++) {
|
for (int i = 0; i < map.size.x * map.size.y; i++) {
|
||||||
Uint32 type = tile_infos[map.tiles[i] & 0xffff].type;
|
Uint16 id = tile_infos[map.tiles[i]].serialization_id;
|
||||||
Uint32 orientation = map.tiles[i] & 0x30000;
|
|
||||||
|
|
||||||
Uint32 to_write = orientation | type;
|
if (!SDL_WriteU16LE(file, id)) {
|
||||||
if (!SDL_WriteU32LE(file, to_write)) {
|
|
||||||
log_error("Failed to write tile to map file.");
|
log_error("Failed to write tile to map file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -443,30 +491,34 @@ static bool load_map(const char *name, Map *result) {
|
|||||||
result->tiles = (Uint32*)malloc(result->size.x * result->size.y * sizeof(Uint32));
|
result->tiles = (Uint32*)malloc(result->size.x * result->size.y * sizeof(Uint32));
|
||||||
|
|
||||||
for (int i = 0; i < result->size.x * result->size.y; i++) {
|
for (int i = 0; i < result->size.x * result->size.y; i++) {
|
||||||
Uint32 tile = 0;
|
if (result->version == 2) {
|
||||||
if (!SDL_ReadU32LE(file, &tile)) {
|
Uint16 serialization_id = 0;
|
||||||
free(result->tiles);
|
if (!SDL_ReadU16LE(file, &serialization_id)) {
|
||||||
return false;
|
free(result->tiles);
|
||||||
}
|
return false;
|
||||||
|
|
||||||
Uint32 type = tile & 0xffff;
|
|
||||||
Uint32 orientation = tile & 0x30000;
|
|
||||||
|
|
||||||
Uint32 kind = 0;
|
|
||||||
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
|
|
||||||
if (tile_infos[i].type == type) {
|
|
||||||
kind = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
result->tiles[i] = orientation | kind;
|
Uint16 info_index = 0;
|
||||||
|
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
|
||||||
|
if (tile_infos[i].serialization_id == serialization_id) {
|
||||||
|
info_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result->tiles[i] = info_index;
|
||||||
|
} else {
|
||||||
|
assert(false && "Tried to load an unsupported map version.");
|
||||||
|
log_error("Tried to load an unsupported map version. Aborting.");
|
||||||
|
free(result->tiles);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer_name[256] = "Map ";
|
char buffer_name[256] = "Map ";
|
||||||
SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name));
|
SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name));
|
||||||
|
|
||||||
result->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, result->size.x * result->size.y * 4, result->tiles, buffer_name);
|
result->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, result->size.x * result->size.y * sizeof(Uint32), result->tiles, buffer_name);
|
||||||
if (!result->gpu_buffer) {
|
if (!result->gpu_buffer) {
|
||||||
log_error("Failed to create buffer. Exiting.");
|
log_error("Failed to create buffer. Exiting.");
|
||||||
return 1;
|
return 1;
|
||||||
@ -533,7 +585,7 @@ static void change_map_size(Map *map, char direction, int amount) {
|
|||||||
to_fill_y_offset = old_map_height;
|
to_fill_y_offset = old_map_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
map->tiles = (Uint32*)malloc(map->size.x * map->size.y * sizeof(Uint32));
|
map->tiles = (Uint32 *)malloc(map->size.x * map->size.y * sizeof(Uint32));
|
||||||
|
|
||||||
for (int y = 0; y < min(old_map_height, map->size.y); y++) {
|
for (int y = 0; y < min(old_map_height, map->size.y); y++) {
|
||||||
for (int x = 0; x < min(old_map_width, map->size.x); x++) {
|
for (int x = 0; x < min(old_map_width, map->size.x); x++) {
|
||||||
@ -549,7 +601,7 @@ static void change_map_size(Map *map, char direction, int amount) {
|
|||||||
|
|
||||||
player.position = clamp(player.position, i32vec2(0, 0), map->size - 2);
|
player.position = clamp(player.position, i32vec2(0, 0), map->size - 2);
|
||||||
|
|
||||||
map->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex, map->size.x * map->size.y * 4, map->tiles, "world_buffer");
|
map->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, map->size.x * map->size.y * sizeof(Uint32), map->tiles, "world_buffer");
|
||||||
if (!map->gpu_buffer) {
|
if (!map->gpu_buffer) {
|
||||||
log_error("Failed to create buffer. Exiting.");
|
log_error("Failed to create buffer. Exiting.");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -631,7 +683,7 @@ static void blit(char *dst, Sint32 dst_pitch, Sint32 dst_x, Sint32 dst_y, char *
|
|||||||
memmove(&dst[((dst_y + y) * dst_pitch + dst_x) * components], &src[y * src_pitch * components], width * components);
|
memmove(&dst[((dst_y + y) * dst_pitch + dst_x) * components], &src[y * src_pitch * components], width * components);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SelectableTile(const char *label, bool selected, Uint32 tile_index, const ImVec2& image_size, Uint8 orientation = 0) {
|
static bool SelectableTile(const char *label, bool selected, Uint32 tile_index, const ImVec2& image_size) {
|
||||||
const ImGuiContext *context = ImGui::GetCurrentContext();
|
const ImGuiContext *context = ImGui::GetCurrentContext();
|
||||||
const ImVec2 padding = context->Style.FramePadding;
|
const ImVec2 padding = context->Style.FramePadding;
|
||||||
|
|
||||||
@ -641,14 +693,7 @@ static bool SelectableTile(const char *label, bool selected, Uint32 tile_index,
|
|||||||
ImVec2 max = ImGui::GetItemRectMax();
|
ImVec2 max = ImGui::GetItemRectMax();
|
||||||
|
|
||||||
vec4 uv = tile_uvs[tile_index] / (float)TILE_ATLAS_SIZE;
|
vec4 uv = tile_uvs[tile_index] / (float)TILE_ATLAS_SIZE;
|
||||||
|
context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)tile_textures_atlas_view_unorm, min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv.x, uv.y), ImVec2(uv.z, uv.y), ImVec2(uv.z, uv.w), ImVec2(uv.x, uv.w));
|
||||||
switch (orientation) {
|
|
||||||
case 0: context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)tile_textures_atlas_view_unorm, min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv.x, uv.y), ImVec2(uv.z, uv.y), ImVec2(uv.z, uv.w), ImVec2(uv.x, uv.w)); break;
|
|
||||||
case 1: context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)tile_textures_atlas_view_unorm, min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv.z, uv.y), ImVec2(uv.z, uv.w), ImVec2(uv.x, uv.w), ImVec2(uv.x, uv.y)); break;
|
|
||||||
case 2: context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)tile_textures_atlas_view_unorm, min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv.z, uv.w), ImVec2(uv.x, uv.w), ImVec2(uv.x, uv.y), ImVec2(uv.z, uv.y)); break;
|
|
||||||
case 3: context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)tile_textures_atlas_view_unorm, min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv.x, uv.w), ImVec2(uv.x, uv.y), ImVec2(uv.z, uv.y), ImVec2(uv.z, uv.w)); break;
|
|
||||||
default: SDL_assert_always(false); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
@ -1246,6 +1291,21 @@ static bool recreate_tile_textures() {
|
|||||||
.depthOrArrayLayers = 1,
|
.depthOrArrayLayers = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (tile_infos[i].rotation) {
|
||||||
|
Uint32 copy[TILE_SIZE * TILE_SIZE]; memcpy(copy, data, TILE_SIZE * TILE_SIZE * 4);
|
||||||
|
|
||||||
|
for (int y = 0; y < TILE_SIZE; y++) {
|
||||||
|
for (int x = 0; x < TILE_SIZE; x++) {
|
||||||
|
switch(tile_infos[i].rotation) {
|
||||||
|
case 1: ((Uint32 *)data)[(TILE_SIZE - x - 1) * TILE_SIZE + (y)] = copy[y * TILE_SIZE + x]; break;
|
||||||
|
case 2: ((Uint32 *)data)[(TILE_SIZE - y - 1) * TILE_SIZE + (TILE_SIZE - x - 1)] = copy[y * TILE_SIZE + x]; break;
|
||||||
|
case 3: ((Uint32 *)data)[(x) * TILE_SIZE + (TILE_SIZE - y - 1)] = copy[y * TILE_SIZE + x]; break;
|
||||||
|
default: assert(false); break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wgpuQueueWriteTexture(queue, &texel_copy_texture_info, data, width * height * 4, &texel_copy_buffer_layout, &extent);
|
wgpuQueueWriteTexture(queue, &texel_copy_texture_info, data, width * height * 4, &texel_copy_buffer_layout, &extent);
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
@ -1277,39 +1337,13 @@ static Uint32 get_corner_info(Sint32 tile_pos_x, Sint32 tile_pos_y) {
|
|||||||
if (tile_pos_x < 0 || tile_pos_x >= current_map.size.x || tile_pos_y < 0 || tile_pos_y >= current_map.size.y)
|
if (tile_pos_x < 0 || tile_pos_x >= current_map.size.x || tile_pos_y < 0 || tile_pos_y >= current_map.size.y)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Uint32 tile = current_map.tiles[tile_pos_y * current_map.size.x + tile_pos_x];
|
return tile_infos[current_map.tiles[tile_pos_y * current_map.size.x + tile_pos_x]].corner_info;
|
||||||
|
|
||||||
Uint32 index = tile & 0xffff;
|
|
||||||
Uint32 rotation = (tile & 0x30000) >> 16;
|
|
||||||
|
|
||||||
Uint32 base_corner_info = tile_infos[index].corner_info;
|
|
||||||
|
|
||||||
switch (rotation) {
|
|
||||||
case 0: return base_corner_info;
|
|
||||||
case 1: return std::rotl(base_corner_info, 8);
|
|
||||||
case 2: return std::rotl(base_corner_info, 16);
|
|
||||||
case 3: return std::rotl(base_corner_info, 24);
|
|
||||||
default: return tile_infos[0].corner_info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 find_matching_tile(Uint32 corner_info) {
|
static Uint32 find_matching_tile(Uint32 corner_info) {
|
||||||
Uint32 corner_info_1 = std::rotr(corner_info, 8);
|
|
||||||
Uint32 corner_info_2 = std::rotr(corner_info, 16);
|
|
||||||
Uint32 corner_info_3 = std::rotr(corner_info, 24);
|
|
||||||
|
|
||||||
for (Uint32 i = 0; i < SDL_arraysize(tile_infos); i++) {
|
for (Uint32 i = 0; i < SDL_arraysize(tile_infos); i++) {
|
||||||
if (corner_info == tile_infos[i].corner_info)
|
if (corner_info == tile_infos[i].corner_info)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
if (corner_info_1 == tile_infos[i].corner_info)
|
|
||||||
return (1 << 16) | i;
|
|
||||||
|
|
||||||
if (corner_info_2 == tile_infos[i].corner_info)
|
|
||||||
return (2 << 16) | i;
|
|
||||||
|
|
||||||
if (corner_info_3 == tile_infos[i].corner_info)
|
|
||||||
return (3 << 16) | i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1342,7 +1376,7 @@ static void change_map_tile(Sint32 pos_x, Sint32 pos_y, TileKind kind) {
|
|||||||
if (0 <= pos_x + 0 && pos_x + 0 < current_map.size.x && 0 <= pos_y + 0 && pos_y + 0 < current_map.size.y)
|
if (0 <= pos_x + 0 && pos_x + 0 < current_map.size.x && 0 <= pos_y + 0 && pos_y + 0 < current_map.size.y)
|
||||||
current_map.tiles[(pos_y + 0) * current_map.size.x + pos_x + 0] = find_matching_tile(corner_infos[3]);
|
current_map.tiles[(pos_y + 0) * current_map.size.x + pos_x + 0] = find_matching_tile(corner_infos[3]);
|
||||||
|
|
||||||
update_buffer(current_map.gpu_buffer, 0, current_map.size.x * current_map.size.y * sizeof(Uint32), current_map.tiles);
|
update_buffer(current_map.gpu_buffer, 0, current_map.size.x * current_map.size.y * sizeof(Uint16), current_map.tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SameLineOrWrap(const ImVec2& size) {
|
static void SameLineOrWrap(const ImVec2& size) {
|
||||||
@ -1671,18 +1705,6 @@ static void process_event_editor(SDL_Event event) {
|
|||||||
|
|
||||||
if (io.WantCaptureKeyboard)
|
if (io.WantCaptureKeyboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDL_Keymod modifiers = SDL_GetModState();
|
|
||||||
|
|
||||||
if (event.key.key == SDLK_R) {
|
|
||||||
if (selected_tile != -1 && selected_rotation != -1) {
|
|
||||||
if (modifiers & SDL_KMOD_SHIFT) {
|
|
||||||
selected_rotation = (selected_rotation - 1) & 3;
|
|
||||||
} else {
|
|
||||||
selected_rotation = (selected_rotation + 1) & 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_WHEEL: {
|
case SDL_EVENT_MOUSE_WHEEL: {
|
||||||
@ -1786,12 +1808,7 @@ static void process_event_editor(SDL_Event event) {
|
|||||||
|
|
||||||
for (Sint32 y = start_y; y <= end_y; y++) {
|
for (Sint32 y = start_y; y <= end_y; y++) {
|
||||||
for (Sint32 x = start_x; x <= end_x; x++) {
|
for (Sint32 x = start_x; x <= end_x; x++) {
|
||||||
if (selected_rotation == -1) {
|
current_map.tiles[x + current_map.size.x * y] = selected_tile;
|
||||||
Sint32 rotation = SDL_rand(4);
|
|
||||||
current_map.tiles[x + current_map.size.x * y] = ((rotation & 3) << 16) | selected_tile;
|
|
||||||
} else {
|
|
||||||
current_map.tiles[x + current_map.size.x * y] = ((selected_rotation & 3) << 16) | selected_tile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,44 +1999,13 @@ static void update_state_editor() {
|
|||||||
if (i != 0)
|
if (i != 0)
|
||||||
SameLineOrWrap(ImVec2(32, 32));
|
SameLineOrWrap(ImVec2(32, 32));
|
||||||
|
|
||||||
if (SelectableTile("##tile", selected_tile == i, i, ImVec2(32, 32), SDL_max(selected_rotation, 0))) {
|
if (SelectableTile("##tile", selected_tile == i, i, ImVec2(32, 32))) {
|
||||||
selected_tile_kind = -1;
|
selected_tile_kind = -1;
|
||||||
selected_tile = i;
|
selected_tile = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_tile != -1) {
|
|
||||||
ImGui::Text("Rotation:");
|
|
||||||
|
|
||||||
if (SelectableTile("##None", selected_rotation == 0, selected_tile, ImVec2(32, 32), 0))
|
|
||||||
selected_rotation = 0;
|
|
||||||
|
|
||||||
|
|
||||||
SameLineOrWrap(ImVec2(32, 32));
|
|
||||||
if (SelectableTile("##90", selected_rotation == 1, selected_tile, ImVec2(32, 32), 1))
|
|
||||||
selected_rotation = 1;
|
|
||||||
|
|
||||||
SameLineOrWrap(ImVec2(32, 32));
|
|
||||||
if (SelectableTile("##180", selected_rotation == 2, selected_tile, ImVec2(32, 32), 2))
|
|
||||||
selected_rotation = 2;
|
|
||||||
|
|
||||||
SameLineOrWrap(ImVec2(32, 32));
|
|
||||||
if (SelectableTile("##270", selected_rotation == 3, selected_tile, ImVec2(32, 32), 3))
|
|
||||||
selected_rotation = 3;
|
|
||||||
|
|
||||||
if (ImGui::Selectable("Random", selected_rotation == -1))
|
|
||||||
selected_rotation = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selected_tile != -1 && ImGui::IsWindowFocused() && ImGui::IsKeyPressed(ImGuiKey_R, false)) {
|
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
|
||||||
selected_rotation = (selected_rotation - 1) & 3;
|
|
||||||
} else {
|
|
||||||
selected_rotation = (selected_rotation + 1) & 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ struct VertexShaderInput {
|
|||||||
// Per Instance
|
// Per Instance
|
||||||
@builtin(instance_index) instance_index: u32,
|
@builtin(instance_index) instance_index: u32,
|
||||||
|
|
||||||
@location(2) tile_info: u32,
|
@location(2) tile: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexShaderOutput {
|
struct VertexShaderOutput {
|
||||||
@ -36,21 +36,11 @@ struct Per_Frame_Data {
|
|||||||
@vertex fn main_vertex(input: VertexShaderInput) -> VertexShaderOutput {
|
@vertex fn main_vertex(input: VertexShaderInput) -> VertexShaderOutput {
|
||||||
var output: VertexShaderOutput;
|
var output: VertexShaderOutput;
|
||||||
|
|
||||||
let tile_type = extractBits(input.tile_info, 0, 16);
|
|
||||||
let rotation = extractBits(input.tile_info, 16, 2);
|
|
||||||
|
|
||||||
let tile_pos = vec2<f32>(f32(input.instance_index % per_frame.map_width), f32(input.instance_index / per_frame.map_width)) - vec2<f32>(0.5, 0.5);
|
let tile_pos = vec2<f32>(f32(input.instance_index % per_frame.map_width), f32(input.instance_index / per_frame.map_width)) - vec2<f32>(0.5, 0.5);
|
||||||
|
|
||||||
output.tile = tile_type;
|
output.tile = input.tile;
|
||||||
output.pos = vec4<f32>(tile_pos + input.pos.xy, 0, 1) * view_projection_matrix;
|
output.pos = vec4<f32>(tile_pos + input.pos.xy, 0, 1) * view_projection_matrix;
|
||||||
|
output.uv = input.uv;
|
||||||
switch (rotation) {
|
|
||||||
case 0: { output.uv = vec2<f32>( input.uv.x, input.uv.y); }
|
|
||||||
case 1: { output.uv = vec2<f32>(1.0 - input.uv.y, input.uv.x); }
|
|
||||||
case 2: { output.uv = vec2<f32>(1.0 - input.uv.x, 1.0 - input.uv.y); }
|
|
||||||
case 3: { output.uv = vec2<f32>( input.uv.y, 1.0 - input.uv.x); }
|
|
||||||
default: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user