diff options
| author | tech kaczynski <tk@techkaczynski.dev> | 2026-11-02 03:23:17 +1000 |
|---|---|---|
| committer | tech kaczynski <tk@techkaczynski.dev> | 2026-11-02 03:23:17 +1000 |
| commit | b47b2e022bfa74cd94d3296aae6bd34ca4afff02 (patch) | |
| tree | 5fa05b743289e1ab877a85c1bf1874be2736f04f /save.c | |
| parent | 040a896cb98963c74916c0b833efa9df2ef965e3 (diff) | |
new shaders for foliage, new material settings, added lots of assets.
Diffstat (limited to 'save.c')
| -rw-r--r-- | save.c | 143 |
1 files changed, 142 insertions, 1 deletions
@@ -564,6 +564,10 @@ read_material_chunk(FILE *fp, SaveLoadContext *ctx, MaterialProperty prop) { (slots - model->mat_cnt) * sizeof(*materials)); + for (size_t j = model->mat_cnt; j < slots; ++j) { + materials[j].uv_scale = (Vec2){1, 1}; + } + model->materials = materials; model->mat_cnt = slots; } @@ -589,6 +593,24 @@ read_material_chunk(FILE *fp, SaveLoadContext *ctx, MaterialProperty prop) { } key[key_len] = '\0'; + + if (prop == MAT_PROP_SHADER) { + cstr replacement = NULL; + + if (strcmp(key, "model") == 0) { + replacement = "default"; + } else if (strcmp(key, "model_cutoff") == 0) { + replacement = "alpha_cutoff"; + } else if (strcmp(key, "vegetation") == 0) { + replacement = "alpha_cutoff_nocull"; + } + + if (replacement) { + free(key); + key = strdup(replacement); + } + } + *field = key; } @@ -657,6 +679,118 @@ write_material_chunk(FILE *fp, MaterialProperty prop) { } static bool +read_material_uv_chunk(FILE *fp, SaveLoadContext *ctx) { + u32 count; + if (!read_u32_le(fp, &count)) { + return false; + } + + for (u32 i = 0; i < count; ++i) { + u64 pid; + u32 mat_idx; + Vec2 scale, offset; + + if (!read_u64_le(fp, &pid) || + !read_u32_le(fp, &mat_idx) || + !read_f32_le(fp, &scale.x) || + !read_f32_le(fp, &scale.y) || + !read_f32_le(fp, &offset.x) || + !read_f32_le(fp, &offset.y)) { + return false; + } + + if (!pid || pid >= ctx->next_pid || + mat_idx == UINT32_MAX) { + return false; + } + + Entity *ent = entity_get(entity_id_from_pid(pid)); + if (!ent || !ent->mdl.has) { + return false; + } + + ModelCmp *model = &ent->mdl; + + if (mat_idx >= model->mat_cnt) { + size_t slots = (size_t)mat_idx + 1; + if (slots > SIZE_MAX / sizeof(MaterialOverride)) { + return false; + } + + MaterialOverride *materials; + materials = realloc(model->materials, + slots * sizeof(*materials)); + + if (!materials) { + return false; + } + + memset(materials + model->mat_cnt, 0, + (slots - model->mat_cnt) * + sizeof(*materials)); + + for (size_t j = model->mat_cnt; j < slots; ++j) { + materials[j].uv_scale = (Vec2){1, 1}; + } + + model->materials = materials; + model->mat_cnt = slots; + } + + MaterialOverride *material; + material = &model->materials[mat_idx]; + material->uv_scale = scale; + material->uv_offset = offset; + } + + return true; +} + +static bool +write_material_uv_chunk(FILE *fp) { + SaveChunk chunk = {0}; + u32 count = 0; + + for (u32 i = 0; i < entity_count(); ++i) { + const Entity *ent = &entity_data()[i]; + + if (!ent->pid || !ent->mdl.has) { + continue; + } + + count += ent->mdl.mat_cnt; + } + + if (!chunk_begin(fp, "MUVS", &chunk) || !write_u32_le(fp, count)) { + return false; + } + + for (u32 i = 0; i < entity_count(); ++i) { + const Entity *ent = &entity_data()[i]; + + if (!ent->pid || !ent->mdl.has) { + continue; + } + + for (u32 j = 0; j < ent->mdl.mat_cnt; ++j) { + const MaterialOverride *material; + material = &ent->mdl.materials[j]; + + if (!write_u64_le(fp, ent->pid) || + !write_u32_le(fp, j) || + !write_f32_le(fp, material->uv_scale.x) || + !write_f32_le(fp, material->uv_scale.y) || + !write_f32_le(fp, material->uv_offset.x) || + !write_f32_le(fp, material->uv_offset.y)) { + return false; + } + } + } + + return chunk_end(fp, &chunk); +} + +static bool read_physics_shape(FILE *fp, PhysicsShape *shape) { *shape = (PhysicsShape){0}; @@ -1192,9 +1326,15 @@ save_file_read(cstr path) { MaterialProperty prop; prop = memcmp(label, "MTEX", 4) == 0 ? - MAT_PROP_TEXTURE : MAT_PROP_SHADER; + MAT_PROP_TEXTURE : MAT_PROP_SHADER; success = read_material_chunk(fp, &ctx, prop); + } else if (memcmp(label, "MUVS", 4) == 0) { + if (!read_entt) { + success = false; + break; + } + success = read_material_uv_chunk(fp, &ctx); } else if (memcmp(label, "PHYS", 4) == 0) { if (!read_entt) { TraceLog(LOG_ERROR, "PHYS found before ENTT."); @@ -1257,6 +1397,7 @@ save_file_write(cstr path) { write_model_chunk(fp) && write_material_chunk(fp, MAT_PROP_TEXTURE) && write_material_chunk(fp, MAT_PROP_SHADER) && + write_material_uv_chunk(fp) && write_physics_chunk(fp); if (fclose(fp) != 0) { |
