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
This commit is contained in:
Nunuhara Cabbage
2022-06-12 19:03:41 -07:00
parent b60cce3e8f
commit e78119bf5a
7 changed files with 103 additions and 100 deletions
+3 -9
View File
@@ -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;
}
+7 -6
View File
@@ -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);
+3 -2
View File
@@ -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));
+61 -60
View File
@@ -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);
}
+15 -7
View File
@@ -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 */
+13 -14
View File
@@ -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, &params);
break;
case PARTS_TEXT:
parts_render_text(parts, &params);
parts_render_text(parts, &state->common, &params);
break;
}
}
+1 -2
View File
@@ -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)