replace map width/height and player pos_x/pos_y with i32vec2 size and position respectively

This commit is contained in:
Sven Balzer 2026-04-15 11:27:08 +02:00
parent 4ec664c8db
commit ba39a0e5eb

View File

@ -246,9 +246,7 @@ static Instance player_instance = {{ 0.0f, 0.0f }};
struct Map {
Uint32 version;
Sint32 width;
Sint32 height;
i32vec2 size;
Uint32 *tiles;
char name[64];
@ -258,23 +256,17 @@ struct Map {
static Map current_map;
struct Player {
Sint32 pos_x;
Sint32 pos_y;
i32vec2 position;
};
static Player player;
typedef struct Sint32x2 {
Sint32 x;
Sint32 y;
} Sint32x2;
struct PerFrame {
Sint32x2 drag_start;
Sint32x2 mouse;
vec2 grid_offset;
Sint32 grid_width;
Sint32 map_width;
i32vec2 drag_start;
i32vec2 mouse;
vec2 grid_offset;
Sint32 grid_width;
Sint32 map_width;
};
static PerFrame per_frame = {};
@ -371,17 +363,17 @@ static bool save_map(Map map) {
return false;
}
if (!SDL_WriteS32LE(file, map.width)) {
if (!SDL_WriteS32LE(file, map.size.x)) {
log_error("Failed to write width to map file.");
return false;
}
if (!SDL_WriteS32LE(file, map.height)) {
if (!SDL_WriteS32LE(file, map.size.y)) {
log_error("Failed to write height to map file.");
return false;
}
for (int i = 0; i < map.width * map.height; i++) {
for (int i = 0; i < map.size.x * map.size.y; i++) {
Uint32 type = tile_infos[map.tiles[i] & 0xffff].type;
Uint32 orientation = map.tiles[i] & 0x30000;
@ -423,19 +415,19 @@ static bool load_map(const char *name, Map *result) {
return false;
}
if (!SDL_ReadS32LE(file, &result->width)) {
if (!SDL_ReadS32LE(file, &result->size.x)) {
log_error("Failed read width from map file.");
return false;
}
if (!SDL_ReadS32LE(file, &result->height)) {
if (!SDL_ReadS32LE(file, &result->size.y)) {
log_error("Failed read height from map file.");
return false;
}
result->tiles = (Uint32*)malloc(result->width * result->height * sizeof(Uint32));
result->tiles = (Uint32*)malloc(result->size.x * result->size.y * sizeof(Uint32));
for (int i = 0; i < result->width * result->height; i++) {
for (int i = 0; i < result->size.x * result->size.y; i++) {
Uint32 tile = 0;
if (!SDL_ReadU32LE(file, &tile)) {
free(result->tiles);
@ -459,7 +451,7 @@ static bool load_map(const char *name, Map *result) {
char buffer_name[256] = "Map ";
SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name));
result->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, result->width * result->height * 4, result->tiles, buffer_name);
result->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, result->size.x * result->size.y * 4, result->tiles, buffer_name);
if (!result->gpu_buffer) {
log_error("Failed to create buffer. Exiting.");
return 1;
@ -470,8 +462,7 @@ static bool load_map(const char *name, Map *result) {
}
static void unload_map(Map *map) {
map->width = 0;
map->height = 0;
map->size = i32vec2(0, 0);
free(map->tiles);
SDL_free(map->name);
wgpuBufferRelease(map->gpu_buffer);
@ -480,22 +471,22 @@ static void unload_map(Map *map) {
static void change_map_size(Map *map, char direction, int amount) {
WGPUBuffer old_gpu_buffer = map->gpu_buffer;
Uint32 *old_map = map->tiles;
Sint32 old_map_width = map->width;
Sint32 old_map_height = map->height;
Sint32 old_map_width = map->size.x;
Sint32 old_map_height = map->size.y;
Sint32 new_x_offset = 0;
Sint32 new_y_offset = 0;
Sint32 old_x_offset = 0;
Sint32 old_y_offset = 0;
Sint32 to_fill_width = map->width;
Sint32 to_fill_height = map->height;
Sint32 to_fill_width = map->size.x;
Sint32 to_fill_height = map->size.y;
Sint32 to_fill_x_offset = 0;
Sint32 to_fill_y_offset = 0;
if (direction == 'W') {
player.pos_x = player.pos_x + amount;
map->width += amount;
player.position.x = player.position.x + amount;
map->size.x += amount;
to_fill_width = amount;
if (amount < 0)
@ -505,8 +496,8 @@ static void change_map_size(Map *map, char direction, int amount) {
}
if (direction == 'N') {
player.pos_y = player.pos_y + amount;
map->height += amount;
player.position.y = player.position.y + amount;
map->size.y += amount;
to_fill_height = amount;
if (amount < 0)
@ -516,35 +507,34 @@ static void change_map_size(Map *map, char direction, int amount) {
}
if (direction == 'E') {
map->width += amount;
map->size.x += amount;
to_fill_width = amount;
to_fill_x_offset = old_map_width;
}
if (direction == 'S') {
map->height += amount;
map->size.y += amount;
to_fill_height = amount;
to_fill_y_offset = old_map_height;
}
map->tiles = (Uint32*)malloc(map->width * map->height * sizeof(Uint32));
map->tiles = (Uint32*)malloc(map->size.x * map->size.y * sizeof(Uint32));
for (int y = 0; y < min(old_map_height, map->height); y++) {
for (int x = 0; x < min(old_map_width, map->width); x++) {
map->tiles[(y + new_y_offset) * map->width + (x + new_x_offset)] = old_map[(y + old_y_offset) * old_map_width + (x + old_x_offset)];
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++) {
map->tiles[(y + new_y_offset) * map->size.x + (x + new_x_offset)] = old_map[(y + old_y_offset) * old_map_width + (x + old_x_offset)];
}
}
for (int y = 0; y < to_fill_height; y++) {
for (int x = 0; x < to_fill_width; x++) {
map->tiles[(y + to_fill_y_offset) * map->width + (x + to_fill_x_offset)] = 1;
map->tiles[(y + to_fill_y_offset) * map->size.x + (x + to_fill_x_offset)] = 1;
}
}
player.pos_x = clamp(0, player.pos_x, map->width - 1);
player.pos_y = clamp(0, player.pos_y, map->height - 1);
player.position = clamp(player.position, i32vec2(0, 0), map->size - 2);
map->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex, map->width * map->height * 4, map->tiles, "world_buffer");
map->gpu_buffer = create_buffer(WGPUBufferUsage_Vertex, map->size.x * map->size.y * 4, map->tiles, "world_buffer");
if (!map->gpu_buffer) {
log_error("Failed to create buffer. Exiting.");
exit(1);
@ -1269,10 +1259,10 @@ static bool imgui_time_picker(const char *label, int time[3]) {
}
static Uint32 get_corner_info(Sint32 tile_pos_x, Sint32 tile_pos_y) {
if (tile_pos_x < 0 || tile_pos_x >= current_map.width || tile_pos_y < 0 || tile_pos_y >= current_map.height)
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;
Uint32 tile = current_map.tiles[tile_pos_y * current_map.width + tile_pos_x];
Uint32 tile = current_map.tiles[tile_pos_y * current_map.size.x + tile_pos_x];
Uint32 index = tile & 0xffff;
Uint32 rotation = (tile & 0x30000) >> 16;
@ -1325,19 +1315,19 @@ static void change_map_tile(Sint32 pos_x, Sint32 pos_y, TileKind kind) {
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 + 0 && pos_x + 0 < current_map.size.x && 0 <= pos_y + 1 && pos_y + 1 < current_map.size.y)
current_map.tiles[(pos_y + 1) * current_map.size.x + 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)
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.size.x && 0 <= pos_y + 1 && pos_y + 1 < current_map.size.y)
current_map.tiles[(pos_y + 1) * current_map.size.x + 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)
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos[2]);
if (0 <= pos_x + 1 && pos_x + 1 < 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 + 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)
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos[3]);
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]);
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.size.x * current_map.size.y * sizeof(Uint32), current_map.tiles);
}
static void SameLineOrWrap(const ImVec2& size) {
@ -1347,7 +1337,7 @@ static void SameLineOrWrap(const ImVec2& size) {
ImGui::SameLine();
}
static Sint32x2 grid_tile_pos_from_floor_intersection(vec2 floor_intersection) {
static i32vec2 grid_tile_pos_from_floor_intersection(vec2 floor_intersection) {
return {
(Sint32)SDL_floorf(floor_intersection.x + (selected_tile == -1 ? 0.5f : 1.0f)),
(Sint32)SDL_floorf(floor_intersection.y + (selected_tile == -1 ? 0.5f : 1.0f)),
@ -2041,19 +2031,19 @@ int main(int argc, char **argv) {
SDL_Keymod modifiers = SDL_GetModState();
if (event.key.key == SDLK_UP || event.key.key == SDLK_W) {
player.pos_y = clamp(0, player.pos_y + 1, current_map.height - 2);
player.position.y = clamp(0, player.position.y + 1, current_map.size.y - 2);
}
if (event.key.key == SDLK_LEFT || event.key.key == SDLK_A) {
player.pos_x = clamp(0, player.pos_x - 1, current_map.width - 2);
player.position.x = clamp(0, player.position.x - 1, current_map.size.x - 2);
}
if (event.key.key == SDLK_DOWN || event.key.key == SDLK_S) {
player.pos_y = clamp(0, player.pos_y - 1, current_map.height - 2);
player.position.y = clamp(0, player.position.y - 1, current_map.size.y - 2);
}
if (event.key.key == SDLK_RIGHT || event.key.key == SDLK_D) {
player.pos_x = clamp(0, player.pos_x + 1, current_map.width - 2);
player.position.x = clamp(0, player.position.x + 1, current_map.size.x - 2);
}
if (event.key.key == SDLK_F1) {
@ -2101,19 +2091,19 @@ int main(int argc, char **argv) {
continue;
vec2 floor_intersection = get_floor_intersection_of_mouse(vec2(event.button.x, event.button.y));
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
drag_start_pos = floor_intersection;
if (selected_tile_kind != -1) {
change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind);
if (-1 <= tile_pos.x && tile_pos.x < current_map.width && -1 <= tile_pos.y && tile_pos.y < current_map.height) {
if (-1 <= tile_pos.x && tile_pos.x < current_map.size.x && -1 <= tile_pos.y && tile_pos.y < current_map.size.y) {
dragging_tile_change = true;
}
}
if (0 <= tile_pos.x && tile_pos.x < current_map.width && 0 <= tile_pos.y && tile_pos.y < current_map.height) {
if (0 <= tile_pos.x && tile_pos.x < current_map.size.x && 0 <= tile_pos.y && tile_pos.y < current_map.size.y) {
dragging_tile_change = true;
}
@ -2125,7 +2115,7 @@ int main(int argc, char **argv) {
change_map_size(&current_map, 'W', 1);
}
if (modifiers & SDL_KMOD_SHIFT && tile_pos.x == current_map.width) {
if (modifiers & SDL_KMOD_SHIFT && tile_pos.x == current_map.size.x) {
if (modifiers & SDL_KMOD_CTRL)
change_map_size(&current_map, 'E', -1);
else
@ -2139,7 +2129,7 @@ int main(int argc, char **argv) {
change_map_size(&current_map, 'N', 1);
}
if (modifiers & SDL_KMOD_SHIFT && tile_pos.y == current_map.height) {
if (modifiers & SDL_KMOD_SHIFT && tile_pos.y == current_map.size.y) {
if (modifiers & SDL_KMOD_CTRL)
change_map_size(&current_map, 'S', -1);
else
@ -2153,12 +2143,12 @@ int main(int argc, char **argv) {
if (selected_tile != -1 && dragging_tile_change) {
vec2 floor_intersection = get_floor_intersection_of_mouse(vec2(event.button.x, event.button.y));
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
Sint32 tile_x = clamp(0, tile_pos.x, current_map.width - 1);
Sint32 tile_y = clamp(0, tile_pos.y, current_map.height - 1);
Sint32 tile_x = clamp(0, tile_pos.x, current_map.size.x - 1);
Sint32 tile_y = clamp(0, tile_pos.y, current_map.size.y - 1);
Sint32x2 drag_start = grid_tile_pos_from_floor_intersection(drag_start_pos);
i32vec2 drag_start = grid_tile_pos_from_floor_intersection(drag_start_pos);
Sint32 start_x = min(tile_x, drag_start.x);
Sint32 start_y = min(tile_y, drag_start.y);
@ -2170,14 +2160,14 @@ int main(int argc, char **argv) {
for (Sint32 x = start_x; x <= end_x; x++) {
if (selected_rotation == -1) {
Sint32 rotation = SDL_rand(4);
current_map.tiles[x + current_map.width * y] = ((rotation & 3) << 16) | selected_tile;
current_map.tiles[x + current_map.size.x * y] = ((rotation & 3) << 16) | selected_tile;
} else {
current_map.tiles[x + current_map.width * y] = ((selected_rotation & 3) << 16) | selected_tile;
current_map.tiles[x + current_map.size.x * y] = ((selected_rotation & 3) << 16) | selected_tile;
}
}
}
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.size.x * current_map.size.y * sizeof(Uint32), current_map.tiles);
}
dragging_tile_change = false;
@ -2188,7 +2178,7 @@ int main(int argc, char **argv) {
if (selected_tile_kind != -1 && dragging_tile_change) {
vec2 floor_intersection = get_floor_intersection_of_mouse(mouse_pos);
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind);
}
} break;
@ -2198,19 +2188,19 @@ int main(int argc, char **argv) {
continue;
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_UP) {
player.pos_y = clamp(0, player.pos_y + 1, current_map.height - 2);
player.position.y = clamp(0, player.position.y + 1, current_map.size.y - 2);
}
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) {
player.pos_x = clamp(0, player.pos_x - 1, current_map.width - 2);
player.position.x = clamp(0, player.position.x - 1, current_map.size.x - 2);
}
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) {
player.pos_y = clamp(0, player.pos_y - 1, current_map.height - 2);
player.position.y = clamp(0, player.position.y - 1, current_map.size.y - 2);
}
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) {
player.pos_x = clamp(0, player.pos_x + 1, current_map.width - 2);
player.position.x = clamp(0, player.position.x + 1, current_map.size.x - 2);
}
} break;
}
@ -2264,8 +2254,7 @@ int main(int argc, char **argv) {
ZoneScopedN("Update");
{
ZoneScopedN("player_instance_buffer");
player_instance.pos.x = player.pos_x;
player_instance.pos.y = player.pos_y;
player_instance.pos = player.position;
update_buffer(player_instance_buffer, 0, sizeof(player_instance), &player_instance);
}
@ -2275,8 +2264,8 @@ int main(int argc, char **argv) {
float aspect_ratio = ((float) window_width / (float) window_height);
view_matrix = view (vec3((float)player.pos_x, (float)player.pos_y, 0), radians(camera_tilt), camera_distance);
inverse_view_matrix = inverse_view(vec3((float)player.pos_x, (float)player.pos_y, 0), radians(camera_tilt), camera_distance);
view_matrix = view (vec3(player.position, 0), radians(camera_tilt), camera_distance);
inverse_view_matrix = inverse_view(vec3(player.position, 0), radians(camera_tilt), camera_distance);
projection_matrix = projection (radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
inverse_projection_matrix = inverse_projection(radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
@ -2285,15 +2274,15 @@ int main(int argc, char **argv) {
update_buffer(view_projection_matrix_buffer, 0, sizeof(view_projection_matrix), &view_projection_matrix);
vec2 floor_intersection = get_floor_intersection_of_mouse(mouse_pos);
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
per_frame.map_width = current_map.width;
per_frame.grid_width = selected_tile != -1 ? current_map.width : current_map.width + 1;
per_frame.map_width = current_map.size.x;
per_frame.grid_width = selected_tile != -1 ? current_map.size.x : current_map.size.x + 1;
per_frame.grid_offset = selected_tile != -1 ? vec2(-0.5f, -0.5f) : vec2(-1.0f, -1.0f);
per_frame.mouse = tile_pos;
if (dragging_tile_change && selected_tile != -1) {
Sint32x2 grid_tile_pos = grid_tile_pos_from_floor_intersection(drag_start_pos);
i32vec2 grid_tile_pos = grid_tile_pos_from_floor_intersection(drag_start_pos);
per_frame.drag_start = grid_tile_pos;
} else {
per_frame.drag_start = tile_pos;
@ -2357,7 +2346,7 @@ int main(int argc, char **argv) {
wgpuRenderPassEncoderSetVertexBuffer(render_pass_encoder, 0, vertex_buffer, 0, WGPU_WHOLE_SIZE);
wgpuRenderPassEncoderSetVertexBuffer(render_pass_encoder, 1, current_map.gpu_buffer, 0, WGPU_WHOLE_SIZE);
wgpuRenderPassEncoderSetBindGroup(render_pass_encoder, 1, world_bind_group, 0, NULL);
wgpuRenderPassEncoderDrawIndexed(render_pass_encoder, 6, current_map.height * current_map.width, 0, 0, 0);
wgpuRenderPassEncoderDrawIndexed(render_pass_encoder, 6, current_map.size.y * current_map.size.x, 0, 0, 0);
}
{ // Draw Player
@ -2373,9 +2362,9 @@ int main(int argc, char **argv) {
if (show_tile_picker) { // Draw Grid
ZoneScopedN("Draw Grid");
Uint32 num_grid_cells = current_map.height * current_map.width;
Uint32 num_grid_cells = current_map.size.y * current_map.size.x;
if (selected_tile == -1)
num_grid_cells = (current_map.height + 1) * (current_map.width + 1);
num_grid_cells = (current_map.size.y + 1) * (current_map.size.x + 1);
wgpuRenderPassEncoderSetPipeline(render_pass_encoder, grid_render_pipeline);
wgpuRenderPassEncoderSetIndexBuffer(render_pass_encoder, grid_index_buffer, WGPUIndexFormat_Uint16, 0, WGPU_WHOLE_SIZE);