From e78119bf5aed5590e4e6dabb8405e3aeff2f0bf6 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Sun, 12 Jun 2022 16:05:04 -0700 Subject: [PATCH] parts: refactor pos/size handling Move position/size values around and rename them to reflect what they actually mean: * parts->offset moved to parts_common->origin_offset * parts->pos moved to parts_common->hitbox * x and y coordinates from parts->rect renamed to parts->pos * width and height from parts->rect moved into parts_common --- src/parts/construction.c | 12 +--- src/parts/debug.c | 13 ++-- src/parts/input.c | 5 +- src/parts/parts.c | 121 +++++++++++++++++++------------------ src/parts/parts_internal.h | 22 ++++--- src/parts/render.c | 27 ++++----- src/parts/text.c | 3 +- 7 files changed, 103 insertions(+), 100 deletions(-) diff --git a/src/parts/construction.c b/src/parts/construction.c index 0242806..eae7e5b 100644 --- a/src/parts/construction.c +++ b/src/parts/construction.c @@ -201,9 +201,7 @@ static void build_create(struct parts *parts, struct parts_construction_process { gfx_delete_texture(&cproc->common.texture); gfx_init_texture_rgba(&cproc->common.texture, op->w, op->h, (SDL_Color){0,0,0,0}); - parts->rect.w = op->w; - parts->rect.h = op->h; - parts_recalculate_pos(parts); + parts_set_dims(parts, &cproc->common, op->w, op->h); } static void build_create_pixel_only(struct parts *parts, struct parts_construction_process *cproc, @@ -211,9 +209,7 @@ static void build_create_pixel_only(struct parts *parts, struct parts_constructi { gfx_delete_texture(&cproc->common.texture); gfx_init_texture_rgb(&cproc->common.texture, op->w, op->h, (SDL_Color){0,0,0,255}); - parts->rect.w = op->w; - parts->rect.h = op->h; - parts_recalculate_pos(parts); + parts_set_dims(parts, &cproc->common, op->w, op->h); } static void build_cg(struct parts *parts, struct parts_construction_process *cproc, struct parts_cp_cg *op) @@ -222,8 +218,7 @@ static void build_cg(struct parts *parts, struct parts_construction_process *cpr assert(cg); gfx_delete_texture(&cproc->common.texture); gfx_init_texture_with_cg(&cproc->common.texture, cg); - parts_set_cg_dims(parts, cg); - parts_recalculate_pos(parts); + parts_set_dims(parts, &cproc->common, cg->metrics.w, cg->metrics.h); cg_free(cg); } @@ -274,7 +269,6 @@ bool PE_BuildPartsConstructionProcess(int parts_no, int state) break; } } - parts_recalculate_pos(parts); parts_dirty(parts); return true; } diff --git a/src/parts/debug.c b/src/parts/debug.c index 2974fdd..f58f527 100644 --- a/src/parts/debug.c +++ b/src/parts/debug.c @@ -142,12 +142,15 @@ static void parts_print_state(struct parts_state *state, int indent) printf("{\n"); indent++; + struct parts_common *com = &state->common; + indent_printf(indent, "texture = "); gfx_print_texture(&state->common.texture, indent); printf(",\n"); - indent_printf(indent, "surface_area = "); - gfx_print_rectangle(&state->common.surface_area); - printf(",\n"); + indent_printf(indent, "dims = {w=%d,h=%d},\n", state->common.w, state->common.h); + indent_printf(indent, "origin_offset = "); gfx_print_point(&com->origin_offset); printf(",\n"); + indent_printf(indent, "hitbox = "); gfx_print_rectangle(&com->hitbox); printf(",\n"); + indent_printf(indent, "surface_area = "); gfx_print_rectangle(&com->surface_area); printf(",\n"); switch (state->type) { case PARTS_CG: parts_cg_print(&state->cg, indent); @@ -271,11 +274,9 @@ static void _parts_print(struct parts *parts, int indent) indent_printf(indent, "linked_to = %d,\n", parts->linked_to); indent_printf(indent, "linked_from = %d,\n", parts->linked_from); indent_printf(indent, "alpha = %u,\n", (unsigned)parts->alpha); - indent_printf(indent, "rect = "); gfx_print_rectangle(&parts->rect); printf(",\n"); + indent_printf(indent, "pos = "); gfx_print_point(&parts->pos); printf(",\n"); indent_printf(indent, "z = %d,\n", parts->z); indent_printf(indent, "show = %s,\n", parts->show ? "true" : "false"); - indent_printf(indent, "pos = "); gfx_print_rectangle(&parts->pos); printf(",\n"); - indent_printf(indent, "offset = "); gfx_print_point(&parts->offset); printf(",\n"); indent_printf(indent, "scale = {x=%f,y=%f},\n", parts->scale.x, parts->scale.y); indent_printf(indent, "rotation = {x=%f,y=%f,z=%f},\n", parts->rotation.x, parts->rotation.y, parts->rotation.z); diff --git a/src/parts/input.c b/src/parts/input.c index bf4239a..2585c36 100644 --- a/src/parts/input.c +++ b/src/parts/input.c @@ -36,8 +36,9 @@ static int click_down_parts = 0; static void parts_update_mouse(struct parts *parts, Point cur_pos, bool cur_clicking) { - bool prev_in = SDL_PointInRect(&parts_prev_pos, &parts->pos); - bool cur_in = SDL_PointInRect(&cur_pos, &parts->pos); + Rectangle *hitbox = &parts->states[parts->state].common.hitbox; + bool prev_in = SDL_PointInRect(&parts_prev_pos, hitbox); + bool cur_in = SDL_PointInRect(&cur_pos, hitbox); if (parts->linked_from >= 0 && cur_in != prev_in) { parts_dirty(parts_get(parts->linked_from)); diff --git a/src/parts/parts.c b/src/parts/parts.c index 64004bb..010f5f5 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -230,64 +230,78 @@ struct parts_construction_process *parts_get_construction_process(struct parts * return &parts->states[state].cproc; } -void parts_recalculate_offset(struct parts *parts) +static Point calculate_offset(int mode, int w, int h) { - const int mode = parts->origin_mode; - const int w = parts->rect.w; - const int h = parts->rect.h; - - int x, y; switch (mode) { - case 1: x = 0; y = 0; break; - case 2: x = -w/2; y = 0; break; - case 3: x = -w; y = -h/2; break; - case 4: x = 0; y = -h/2; break; - case 5: x = -w/2; y = -h/2; break; - case 6: x = -w; y = -h/2; break; - case 7: x = 0; y = -h; break; - case 8: x = -w/2; y = -h; break; - case 9: x = -w; y = -h; break; - default: - // why... - x = mode; - y = (3*h)/4; - break; + case 1: return (Point) { 0, 0 }; + case 2: return (Point) { -w/2, 0 }; + case 3: return (Point) { -w, -h/2 }; + case 4: return (Point) { 0, -h/2 }; + case 5: return (Point) { -w/2, -h/2 }; + case 6: return (Point) { -w, -h/2 }; + case 7: return (Point) { 0, -h }; + case 8: return (Point) { -w/2, -h }; + case 9: return (Point) { -w, -h }; + default: return (Point) { mode, (3*h)/4 }; // why... } - - parts->offset.x = x; - parts->offset.y = y; } -void parts_recalculate_pos(struct parts *parts) +/* + * Should be called when: + * - position (parts->pos) changes + * - width or height changes + * - origin mode changes + */ +static void parts_common_recalculate_hitbox(struct parts *parts, struct parts_common *common) { - parts_recalculate_offset(parts); - parts->pos = (Rectangle) { - .x = parts->rect.x + parts->offset.x, - .y = parts->rect.y + parts->offset.y, - .w = parts->rect.w, - .h = parts->rect.h, + common->origin_offset = calculate_offset(parts->origin_mode, common->w, common->h); + common->hitbox = (Rectangle) { + .x = parts->pos.x + common->origin_offset.x, + .y = parts->pos.y + common->origin_offset.y, + .w = common->w, + .h = common->h, }; } +static void parts_recalculate_hitbox(struct parts *parts) +{ + for (int i = 0; i < PARTS_NR_STATES; i++) { + parts_common_recalculate_hitbox(parts, &parts->states[i].common); + } +} + void parts_set_pos(struct parts *parts, Point pos) { - parts->rect.x = pos.x; - parts->rect.y = pos.y; - parts_recalculate_pos(parts); + parts->pos.x = pos.x; + parts->pos.y = pos.y; + parts_recalculate_hitbox(parts); parts_dirty(parts); } +void parts_set_dims(struct parts *parts, struct parts_common *common, int w, int h) +{ + common->w = w; + common->h = h; + parts_common_recalculate_hitbox(parts, common); +} + +void parts_set_origin_mode(struct parts *parts, int origin_mode) +{ + parts->origin_mode = origin_mode; + parts_recalculate_hitbox(parts); +} + void parts_set_scale_x(struct parts *parts, float mag) { parts->scale.x = mag; - parts_recalculate_pos(parts); + parts_recalculate_hitbox(parts); parts_dirty(parts); } void parts_set_scale_y(struct parts *parts, float mag) { parts->scale.y = mag; - parts_recalculate_pos(parts); + parts_recalculate_hitbox(parts); parts_dirty(parts); } @@ -312,16 +326,6 @@ void parts_set_alpha(struct parts *parts, int alpha) parts_dirty(parts); } -void parts_set_cg_dims(struct parts *parts, struct cg *cg) -{ - if (parts->rect.w && parts->rect.w != cg->metrics.w) - WARNING("Width of parts CGs differ: %d / %d", parts->rect.w, cg->metrics.w); - if (parts->rect.h && parts->rect.h != cg->metrics.h) - WARNING("Heights of parts CGs differ: %d / %d", parts->rect.h, cg->metrics.h); - parts->rect.w = cg->metrics.w; - parts->rect.h = cg->metrics.h; -} - static bool parts_set_cg(struct parts *parts, struct cg *cg, int cg_no, int state) { if (!cg) @@ -329,9 +333,8 @@ static bool parts_set_cg(struct parts *parts, struct cg *cg, int cg_no, int stat struct parts_cg *parts_cg = parts_get_cg(parts, state); gfx_delete_texture(&parts_cg->common.texture); gfx_init_texture_with_cg(&parts_cg->common.texture, cg); + parts_set_dims(parts, &parts_cg->common, cg->metrics.w, cg->metrics.h); parts_cg->no = cg_no; - parts_set_cg_dims(parts, cg); - parts_recalculate_pos(parts); parts_dirty(parts); cg_free(cg); return true; @@ -449,8 +452,7 @@ bool parts_set_number(struct parts *parts, int n, int state) x += ch->w + num->space; } - parts->rect.w = w; - parts->rect.h = h; + parts_set_dims(parts, &num->common, w, h); parts_dirty(parts); return true; @@ -620,6 +622,7 @@ bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_tim WARNING("Invalid frame count: %d", nr_frames); } + int w = 0, h = 0; struct parts *parts = parts_get(parts_no); Texture *frames = xcalloc(nr_frames, sizeof(Texture)); for (int i = 0; i < nr_frames; i++) { @@ -632,11 +635,13 @@ bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_tim return false; } gfx_init_texture_with_cg(&frames[i], cg); - parts_set_cg_dims(parts, cg); + w = max(w, cg->metrics.w); + h = max(h, cg->metrics.h); cg_free(cg); } struct parts_animation *anim = parts_get_animation(parts, state); + parts_set_dims(parts, &anim->common, w, h); anim->frames = frames; // free previous value? anim->nr_frames = nr_frames; anim->frame_time = frame_time; @@ -672,8 +677,7 @@ static bool set_gauge_cg(int parts_no, struct cg *cg, int state, bool vert) gfx_init_texture_rgba(&g->common.texture, g->cg.w, g->cg.h, (SDL_Color){0,0,0,255}); gfx_copy_with_alpha_map(&g->common.texture, 0, 0, &g->cg, 0, 0, g->cg.w, g->cg.h); - parts->rect.w = g->cg.w; - parts->rect.h = g->cg.h; + parts_set_dims(parts, &g->common, g->cg.w, g->cg.h); parts_dirty(parts); return true; @@ -913,24 +917,22 @@ void PE_SetMultiplyColor(int PartsNumber, int nR, int nG, int nB); int PE_GetPartsX(int parts_no) { - return parts_get(parts_no)->rect.x; + return parts_get(parts_no)->pos.x; } int PE_GetPartsY(int parts_no) { - return parts_get(parts_no)->rect.y; + return parts_get(parts_no)->pos.y; } int PE_GetPartsWidth(int parts_no, possibly_unused int state) { - // FIXME: use state - return parts_get(parts_no)->rect.w; + return parts_get_width(parts_get(parts_no)); } int PE_GetPartsHeight(int parts_no, possibly_unused int state) { - // FIXME: use state - return parts_get(parts_no)->rect.h; + return parts_get_height(parts_get(parts_no)); } int PE_GetPartsZ(int parts_no) @@ -954,8 +956,7 @@ void PE_GetMultiplyColor(int PartsNumber, int *nR, int *nG, int *nB); void PE_SetPartsOriginPosMode(int parts_no, int origin_pos_mode) { struct parts *parts = parts_get(parts_no); - parts->origin_mode = origin_pos_mode; - parts_recalculate_pos(parts); + parts_set_origin_mode(parts, origin_pos_mode); parts_dirty(parts); } diff --git a/src/parts/parts_internal.h b/src/parts/parts_internal.h index da84b3e..6f618f1 100644 --- a/src/parts/parts_internal.h +++ b/src/parts/parts_internal.h @@ -88,6 +88,9 @@ enum parts_type { struct parts_common { Texture texture; + int w, h; + Point origin_offset; + Rectangle hitbox; Rectangle surface_area; }; @@ -207,12 +210,9 @@ struct parts { int linked_to; int linked_from; uint8_t alpha; - Rectangle rect; int z; bool show; - // The actual hitbox of the sprite (accounting for origin-mode, scale, etc) - Rectangle pos; - Point offset; + Point pos; struct { float x, y; } scale; struct { float x, y, z; } rotation; TAILQ_HEAD(, parts_motion) motion; @@ -229,14 +229,12 @@ struct parts_numeral *parts_get_numeral(struct parts *parts, int state); struct parts_gauge *parts_get_hgauge(struct parts *parts, int state); struct parts_gauge *parts_get_vgauge(struct parts *parts, int state); struct parts_construction_process *parts_get_construction_process(struct parts *parts, int state); -void parts_recalculate_offset(struct parts *parts); -void parts_recalculate_pos(struct parts *parts); void parts_set_pos(struct parts *parts, Point pos); +void parts_set_dims(struct parts *parts, struct parts_common *common, int w, int h); void parts_set_scale_x(struct parts *parts, float mag); void parts_set_scale_y(struct parts *parts, float mag); void parts_set_rotation_z(struct parts *parts, float rot); void parts_set_alpha(struct parts *parts, int alpha); -void parts_set_cg_dims(struct parts *parts, struct cg *cg); bool parts_set_cg_by_index(struct parts *parts, int cg_no, int state); bool parts_set_cg_by_name(struct parts *parts, struct string *cg_name, int state); void parts_set_hgauge_rate(struct parts *parts, float rate, int state); @@ -274,4 +272,14 @@ static inline bool parts_state_valid(int state) return state >= 0 && state <= 2; } +static inline int parts_get_width(struct parts *parts) +{ + return parts->states[parts->state].common.w; +} + +static inline int parts_get_height(struct parts *parts) +{ + return parts->states[parts->state].common.h; +} + #endif /* SYSTEM4_PARTS_INTERNAL_H */ diff --git a/src/parts/render.c b/src/parts/render.c index 5af91e8..29e1cb6 100644 --- a/src/parts/render.c +++ b/src/parts/render.c @@ -41,14 +41,14 @@ static struct { GLint top_right; } parts_shader; -static void parts_render_text(struct parts *parts, struct parts_render_params *params) +static void parts_render_text(struct parts *parts, struct parts_common *common, + struct parts_render_params *params) { - parts_recalculate_offset(parts); Rectangle rect = { - .x = params->offset.x + parts->offset.x, - .y = params->offset.y + parts->offset.y, - .w = parts->rect.w, - .h = parts->rect.h + .x = params->offset.x + common->origin_offset.x, + .y = params->offset.y + common->origin_offset.y, + .w = common->w, + .h = common->h }; gfx_render_texture(&parts->states[parts->state].common.texture, &rect); } @@ -56,8 +56,6 @@ static void parts_render_text(struct parts *parts, struct parts_render_params *p static void parts_render_cg(struct parts *parts, struct parts_common *common, struct parts_render_params *params) { - parts_recalculate_offset(parts); - mat4 mw_transform = GLM_MAT4_IDENTITY_INIT; glm_translate(mw_transform, (vec3) { params->offset.x, params->offset.y, 0 }); // FIXME: need perspective for 3D rotate @@ -65,8 +63,8 @@ static void parts_render_cg(struct parts *parts, struct parts_common *common, //glm_rotate_y(mw_transform, parts->rotation.y, mw_transform); glm_rotate_z(mw_transform, parts->rotation.z, mw_transform); glm_scale(mw_transform, (vec3){ parts->scale.x, parts->scale.y, 1.0 }); - glm_translate(mw_transform, (vec3){ parts->offset.x, parts->offset.y, 0 }); - glm_scale(mw_transform, (vec3){ parts->rect.w, parts->rect.h, 1.0 }); + glm_translate(mw_transform, (vec3){ common->origin_offset.x, common->origin_offset.y, 0 }); + glm_scale(mw_transform, (vec3){ common->w, common->h, 1.0 }); mat4 wv_transform = WV_TRANSFORM(config.view_width, config.view_height); struct gfx_render_job job = { @@ -96,15 +94,16 @@ static void _parts_render(struct parts *parts, struct parts_render_params *paren if (parts->linked_to >= 0) { struct parts *link_parts = parts_get(parts->linked_to); - if (!SDL_PointInRect(&parts_prev_pos, &link_parts->pos)) + struct parts_state *link_state = &link_parts->states[link_parts->state]; + if (!SDL_PointInRect(&parts_prev_pos, &link_state->common.hitbox)) return; } struct parts_render_params params = *parent_params; // modify params per parts values params.alpha *= parts->alpha / 255.0; - params.offset.x += parts->rect.x; - params.offset.y += parts->rect.y; + params.offset.x += parts->pos.x; + params.offset.y += parts->pos.y; // render struct parts_state *state = &parts->states[parts->state]; @@ -119,7 +118,7 @@ static void _parts_render(struct parts *parts, struct parts_render_params *paren parts_render_cg(parts, &state->common, ¶ms); break; case PARTS_TEXT: - parts_render_text(parts, ¶ms); + parts_render_text(parts, &state->common, ¶ms); break; } } diff --git a/src/parts/text.c b/src/parts/text.c index 162d2d9..db775dc 100644 --- a/src/parts/text.c +++ b/src/parts/text.c @@ -74,8 +74,7 @@ static void parts_text_append(struct parts *parts, struct string *text, int stat const unsigned new_height = t->ts.size; t->lines[t->nr_lines-1].height = max(old_height, new_height); } - parts->rect.w = t->cursor.x; - parts->rect.h = t->cursor.y + t->lines[t->nr_lines-1].height; + parts_set_dims(parts, &t->common, t->cursor.x, t->cursor.y + t->lines[t->nr_lines-1].height); } static void parts_text_clear(struct parts *parts, int state)