d_define_method(line, intersect_point)(struct s_object *self, struct s_object *other, struct s_object *intersection) { d_using(line); struct s_line_attributes *other_attributes = d_cast(other, line); struct s_point_attributes *intersection_attributes; double projection_A_ending_x, projection_A_ending_y, projection_B_starting_x, projection_B_starting_y, projection_B_ending_x, projection_B_ending_y, size_A, cos, sin, rotated_B_starting_x, rotated_B_starting_y, rotated_B_ending_x, rotated_B_ending_y, intersection_position; t_boolean result = d_false; projection_A_ending_x = line_attributes->ending_x - line_attributes->starting_x; projection_A_ending_y = line_attributes->ending_y - line_attributes->starting_y; projection_B_starting_x = other_attributes->starting_x - line_attributes->starting_x; projection_B_starting_y = other_attributes->starting_y - line_attributes->starting_y; projection_B_ending_x = other_attributes->ending_x - line_attributes->starting_x; projection_B_ending_y = other_attributes->ending_y - line_attributes->starting_y; size_A = f_math_sqrt((projection_A_ending_x*projection_A_ending_x) + (projection_B_ending_y*projection_B_ending_y), d_math_default_precision); cos = projection_A_ending_x/size_A; sin = projection_A_ending_y/size_A; rotated_B_starting_x = (projection_B_starting_x * cos) + (projection_B_starting_y * sin); rotated_B_starting_y = (projection_B_starting_y * cos) - (projection_B_starting_x * sin); rotated_B_ending_x = (projection_B_ending_x * cos) + (projection_B_ending_y * sin); rotated_B_ending_y = (projection_B_ending_y * cos) - (projection_B_ending_x * sin); if (((rotated_B_starting_y >= 0) && (rotated_B_ending_y < 0)) || ((rotated_B_starting_y < 0) && (rotated_B_ending_y >= 0))) { intersection_position = rotated_B_ending_x + (rotated_B_starting_x - rotated_B_ending_x) * rotated_B_ending_y / (rotated_B_ending_y - rotated_B_starting_y); if ((intersection_position >= 0) && (intersection_position <= size_A)) { if (intersection) if ((intersection_attributes = d_cast(intersection, point))) { intersection_attributes->x = line_attributes->starting_x + (intersection_position * cos); intersection_attributes->y = line_attributes->starting_y + (intersection_position * sin); } result = d_true; } } d_cast_return(result); }
d_define_method(track, is_playing)(struct s_object *self) { d_using(track); t_boolean playing = d_false; if ((track_attributes->channel != d_track_auto_channel) && ((Mix_Playing(track_attributes->channel)) || (Mix_Paused(track_attributes->channel)))) playing = d_true; d_cast_return(playing); }
d_define_method(container, get_drawable)(struct s_object *self, struct s_object *drawable) { d_using(container); struct s_container_drawable *result = NULL; d_foreach(&(container_attributes->entries), result, struct s_container_drawable) if (result->drawable == drawable) break; d_cast_return(result); }
d_define_method(particle, is_completed)(struct s_object *self) { d_using(particle); t_boolean result = d_true; unsigned int index; for (index = 0; index < particle_attributes->configuration.particles; ++index) if ((!particle_attributes->particles[index].was_alive) || (particle_attributes->particles[index].alive)) { result = d_false; break; } d_cast_return(result); }
d_define_method_override(particle, draw)(struct s_object *self, struct s_object *environment) { d_using(particle); unsigned int index, new_particles; struct timeval current, elapsed_update; double real_elapsed_update, local_position_x, local_position_y, position_x, position_y, normalized_R, normalized_G, normalized_B, normalized_A; struct s_drawable_attributes *drawable_attributes_core = d_cast(particle_attributes->drawable_core, drawable), *drawable_attributes_self = d_cast(self, drawable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); struct s_camera_attributes *camera_attributes = d_cast(environment_attributes->current_camera, camera); gettimeofday(¤t, NULL); if (!particle_attributes->initialized) { memcpy(&(particle_attributes->last_generation), ¤t, sizeof(struct timeval)); particle_attributes->initialized = d_true; } timersub(¤t, &(particle_attributes->last_generation), &elapsed_update); real_elapsed_update = elapsed_update.tv_sec + ((double)(elapsed_update.tv_usec) / 1000000.0); if ((new_particles = (unsigned int)(particle_attributes->configuration.emission_rate * real_elapsed_update)) > 0) memcpy(&(particle_attributes->last_generation), ¤t, sizeof(struct timeval)); d_call(self, m_particle_update, new_particles); d_call(&(drawable_attributes_self->point_destination), m_point_get, (double *)&local_position_x, (double *)&local_position_y); for (index = 0; index < particle_attributes->configuration.particles; ++index) if (particle_attributes->particles[index].alive) { /* since the particle is a single object shared between all the emitters stored into the list, we should perform the normalization here, in the draw * method */ normalized_R = ((particle_attributes->particles[index].core.mask_R / 255.0) * (drawable_attributes_self->last_mask_R / 255.0)) * 255.0; normalized_G = ((particle_attributes->particles[index].core.mask_G / 255.0) * (drawable_attributes_self->last_mask_G / 255.0)) * 255.0; normalized_B = ((particle_attributes->particles[index].core.mask_B / 255.0) * (drawable_attributes_self->last_mask_B / 255.0)) * 255.0; normalized_A = ((particle_attributes->particles[index].core.mask_A / 255.0) * (drawable_attributes_self->last_mask_A / 255.0)) * 255.0; d_call(particle_attributes->drawable_core, m_drawable_set_maskRGB, (unsigned int)normalized_R, (unsigned int)normalized_G, (unsigned int)normalized_B); d_call(particle_attributes->drawable_core, m_drawable_set_maskA, (unsigned int)normalized_A); position_x = particle_attributes->particles[index].core.position_x; position_y = particle_attributes->particles[index].core.position_y; d_call(&(drawable_attributes_core->point_destination), m_point_set_x, (double)position_x); d_call(&(drawable_attributes_core->point_destination), m_point_set_y, (double)position_y); drawable_attributes_core->zoom = (particle_attributes->particles[index].core.zoom * drawable_attributes_self->zoom); drawable_attributes_core->angle = (particle_attributes->particles[index].core.angle + drawable_attributes_self->angle); drawable_attributes_core->flip = drawable_attributes_self->flip; if ((d_call(particle_attributes->drawable_core, m_drawable_normalize_scale, camera_attributes->scene_reference_w, camera_attributes->scene_reference_h, camera_attributes->scene_offset_x, camera_attributes->scene_offset_y, camera_attributes->scene_center_x, camera_attributes->scene_center_y, camera_attributes->screen_w, camera_attributes->screen_h, camera_attributes->scene_zoom))) while (((intptr_t)d_call(particle_attributes->drawable_core, m_drawable_draw, environment)) == d_drawable_return_continue); if ((drawable_attributes_self->flags & e_drawable_kind_contour) == e_drawable_kind_contour) d_call(particle_attributes->drawable_core, m_drawable_draw_contour, environment); } d_cast_return(d_drawable_return_last); }
d_define_method_override(checkbox, draw)(struct s_object *self, struct s_object *environment) { d_using(checkbox); struct s_uiable_attributes *uiable_attributes = d_cast(self, uiable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); struct s_drawable_attributes *drawable_attributes_self = d_cast(self, drawable), *drawable_attributes_selected; struct s_object *selected_component = NULL; double position_x, position_y, new_position_x, new_position_y, center_x, center_y, new_center_x, new_center_y, dimension_w_self, dimension_h_self, dimension_w_selected, dimension_h_selected, new_dimension_w, new_dimension_h; int result = (intptr_t)d_call_owner(self, label, m_drawable_draw, environment); /* recall the father's draw method */ d_call(&(drawable_attributes_self->point_destination), m_point_get, &position_x, &position_y); d_call(&(drawable_attributes_self->point_dimension), m_point_get, &dimension_w_self, &dimension_h_self); d_call(&(drawable_attributes_self->point_center), m_point_get, ¢er_x, ¢er_y); if ((checkbox_attributes->is_checked) && (checkbox_attributes->checked)) selected_component = checkbox_attributes->checked; else if ((!checkbox_attributes->is_checked) && (checkbox_attributes->unchecked)) selected_component = checkbox_attributes->unchecked; if (selected_component) { drawable_attributes_selected = d_cast(selected_component, drawable); d_call(&(drawable_attributes_selected->point_dimension), m_point_get, &dimension_w_selected, &dimension_h_selected); new_dimension_h = dimension_h_self - (uiable_attributes->border_h * 2.0); new_dimension_w = (dimension_w_selected * new_dimension_h)/dimension_h_selected; new_position_x = position_x + dimension_w_self - new_dimension_w - uiable_attributes->border_w; new_position_y = position_y + ((dimension_h_self - new_dimension_h) / 2.0); new_center_x = (position_x + center_x) - new_position_x; new_center_y = (position_y + center_y) - new_position_y; d_call(selected_component, m_drawable_set_position, new_position_x, new_position_y); d_call(selected_component, m_drawable_set_center, new_center_x, new_center_y); d_call(selected_component, m_drawable_set_dimension, new_dimension_w, new_dimension_h); drawable_attributes_selected->angle = drawable_attributes_self->angle; drawable_attributes_selected->zoom = drawable_attributes_self->zoom; drawable_attributes_selected->flip = drawable_attributes_self->flip; if ((d_call(selected_component, m_drawable_normalize_scale, environment_attributes->reference_w[environment_attributes->current_surface], environment_attributes->reference_h[environment_attributes->current_surface], environment_attributes->camera_origin_x[environment_attributes->current_surface], environment_attributes->camera_origin_y[environment_attributes->current_surface], environment_attributes->camera_focus_x[environment_attributes->current_surface], environment_attributes->camera_focus_y[environment_attributes->current_surface], environment_attributes->current_w, environment_attributes->current_h, environment_attributes->zoom[environment_attributes->current_surface]))) while(((int)d_call(selected_component, m_drawable_draw, environment)) == d_drawable_return_continue); } d_cast_return(result); }
d_define_method_override(bitmap, draw)(struct s_object *self, struct s_object *environment) { d_using(bitmap); double position_x, position_y, dimension_w, dimension_h, center_x, center_y; struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); SDL_Rect destination; SDL_Point center; d_call(&(drawable_attributes->point_normalized_destination), m_point_get, &position_x, &position_y); d_call(&(drawable_attributes->point_normalized_dimension), m_point_get, &dimension_w, &dimension_h); d_call(&(drawable_attributes->point_normalized_center), m_point_get, ¢er_x, ¢er_y); destination.x = position_x; destination.y = position_y; destination.w = dimension_w; destination.h = dimension_h; center.x = center_x; center.y = center_y; SDL_RenderCopyEx(environment_attributes->renderer, bitmap_attributes->image, NULL, &destination, drawable_attributes->angle, ¢er, drawable_attributes->flip); d_cast_return(d_drawable_return_last); }
d_define_method(fonts, get_font)(struct s_object *self, unsigned int id, int style) { d_using(fonts); if (fonts_attributes->fonts[id].font) TTF_SetFontStyle(fonts_attributes->fonts[id].font, style); d_cast_return(fonts_attributes->fonts[id].font); }
d_define_method(checkbox, get_checked)(struct s_object *self) { d_using(checkbox); d_cast_return(checkbox_attributes->is_checked); }
d_define_method(uiable, draw)(struct s_object *self, struct s_object *environment) { d_using(uiable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); struct s_drawable_attributes *drawable_attributes_self = d_cast(self, drawable), *drawable_attributes_core; double local_x, local_y, local_w, local_h, center_x, center_y, component_w[e_uiable_component_NULL], component_h[e_uiable_component_NULL]; int index; d_call(&(drawable_attributes_self->point_destination), m_point_get, &local_x, &local_y); d_call(&(drawable_attributes_self->point_dimension), m_point_get, &local_w, &local_h); d_call(&(drawable_attributes_self->point_center), m_point_get, ¢er_x, ¢er_y); for (index = 0; index < e_uiable_component_NULL; ++index) if (uiable_attributes->background[index]) { drawable_attributes_core = d_cast(uiable_attributes->background[index], drawable); d_call(&(drawable_attributes_core->point_dimension), m_point_get, &(component_w[index]), &(component_h[index])); } if (uiable_attributes->background[e_uiable_component_center]) { d_call(uiable_attributes->background[e_uiable_component_center], m_drawable_set_position, (local_x-1), (local_y-1)); d_call(uiable_attributes->background[e_uiable_component_center], m_drawable_set_dimension, (local_w+2), (local_h+2)); d_call(uiable_attributes->background[e_uiable_component_center], m_drawable_set_center, (center_x+1), (center_y+1)); } if (uiable_attributes->background[e_uiable_component_corner_top_left]) { d_call(uiable_attributes->background[e_uiable_component_corner_top_left], m_drawable_set_position, (local_x-component_w[e_uiable_component_corner_top_left]), (local_y-component_h[e_uiable_component_corner_top_left])); d_call(uiable_attributes->background[e_uiable_component_corner_top_left], m_drawable_set_center, (center_x+component_w[e_uiable_component_corner_top_left]), (center_y+component_h[e_uiable_component_corner_top_left])); } if (uiable_attributes->background[e_uiable_component_corner_top_right]) { d_call(uiable_attributes->background[e_uiable_component_corner_top_right], m_drawable_set_position, (local_x+local_w), (local_y-component_h[e_uiable_component_corner_top_right])); d_call(uiable_attributes->background[e_uiable_component_corner_top_right], m_drawable_set_center, (center_x-local_w)-1, (center_y+component_h[e_uiable_component_corner_top_right])); } if (uiable_attributes->background[e_uiable_component_corner_bottom_left]) { d_call(uiable_attributes->background[e_uiable_component_corner_bottom_left], m_drawable_set_position, (local_x-component_w[e_uiable_component_corner_bottom_left]), (local_y+local_h)); d_call(uiable_attributes->background[e_uiable_component_corner_bottom_left], m_drawable_set_center, (center_x+component_w[e_uiable_component_corner_bottom_left]), (center_y-local_h)); } if (uiable_attributes->background[e_uiable_component_corner_bottom_right]) { d_call(uiable_attributes->background[e_uiable_component_corner_bottom_right], m_drawable_set_position, (local_x+local_w), (local_y+local_h)); d_call(uiable_attributes->background[e_uiable_component_corner_bottom_right], m_drawable_set_center, (center_x-local_w)-1, (center_y-local_h)-1); } if (uiable_attributes->background[e_uiable_component_top]) { d_call(uiable_attributes->background[e_uiable_component_top], m_drawable_set_position, (local_x-1), (local_y-component_h[e_uiable_component_top])); d_call(uiable_attributes->background[e_uiable_component_top], m_drawable_set_dimension_w, (local_w+2)); d_call(uiable_attributes->background[e_uiable_component_top], m_drawable_set_center, (center_x+1), (center_y+component_h[e_uiable_component_top])); } if (uiable_attributes->background[e_uiable_component_bottom]) { d_call(uiable_attributes->background[e_uiable_component_bottom], m_drawable_set_position, (local_x-1), (local_y+local_h)); d_call(uiable_attributes->background[e_uiable_component_bottom], m_drawable_set_dimension_w, (local_w+2)); d_call(uiable_attributes->background[e_uiable_component_bottom], m_drawable_set_center, (center_x+1), (center_y-local_h)); } if (uiable_attributes->background[e_uiable_component_left]) { d_call(uiable_attributes->background[e_uiable_component_left], m_drawable_set_position, (local_x-component_w[e_uiable_component_left]), (local_y-1)); d_call(uiable_attributes->background[e_uiable_component_left], m_drawable_set_dimension_h, (local_h+2)); d_call(uiable_attributes->background[e_uiable_component_left], m_drawable_set_center, (center_x+component_w[e_uiable_component_left]), (center_y+1)); } if (uiable_attributes->background[e_uiable_component_right]) { d_call(uiable_attributes->background[e_uiable_component_right], m_drawable_set_position, (local_x+local_w), (local_y-1)); d_call(uiable_attributes->background[e_uiable_component_right], m_drawable_set_dimension_h, (local_h+2)); d_call(uiable_attributes->background[e_uiable_component_right], m_drawable_set_center, (center_x-local_w)-1, (center_y+1)); } for (index = 0; index < e_uiable_component_NULL; ++index) if (uiable_attributes->background[index]) { drawable_attributes_core = d_cast(uiable_attributes->background[index], drawable); drawable_attributes_core->angle = drawable_attributes_self->angle; drawable_attributes_core->zoom = drawable_attributes_self->zoom; /* do not inerith the flip (this object, the uiable, doesn't flip) */ if ((d_call(uiable_attributes->background[index], m_drawable_normalize_scale, environment_attributes->reference_w, environment_attributes->reference_h, environment_attributes->camera_origin_x, environment_attributes->camera_origin_y, environment_attributes->camera_focus_x, environment_attributes->camera_focus_y, environment_attributes->current_w, environment_attributes->current_h, environment_attributes->zoom))) while (((int)d_call(uiable_attributes->background[index], m_drawable_draw, environment)) == d_drawable_return_continue); } d_cast_return(d_drawable_return_last); }
d_define_method(label, get_content_char)(struct s_object *self) { d_using(label); d_cast_return(label_attributes->string_content); }
d_define_method_override(label, draw)(struct s_object *self, struct s_object *environment) { d_using(label); struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_uiable_attributes *uiable_attributes = d_cast(self, uiable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); double position_x, position_y, dimension_w, dimension_h, center_x, center_y, width_factor, height_factor; int result = (intptr_t)d_call_owner(self, uiable, m_drawable_draw, environment); /* recall the father's draw method */ SDL_Rect source, destination; SDL_Point center; if (label_attributes->image) { d_call(&(drawable_attributes->point_normalized_destination), m_point_get, &position_x, &position_y); d_call(&(drawable_attributes->point_normalized_dimension), m_point_get, &dimension_w, &dimension_h); d_call(&(drawable_attributes->point_normalized_center), m_point_get, ¢er_x, ¢er_y); width_factor = (dimension_w/label_attributes->last_width); height_factor = (dimension_h/label_attributes->last_height); source.x = 0; source.y = 0; destination.x = (position_x + uiable_attributes->border_w); destination.y = (position_y + uiable_attributes->border_h); if (label_attributes->format == e_label_background_format_fixed) { source.w = d_math_min((label_attributes->last_width - (uiable_attributes->border_w * 2.0)), label_attributes->string_width); source.h = d_math_min((label_attributes->last_height - (uiable_attributes->border_h * 2.0)), label_attributes->string_height); switch (label_attributes->alignment_x) { case e_label_alignment_center: if ((source.x = d_math_max(((label_attributes->string_width-label_attributes->last_width)/2.0), 0)) == 0) destination.x = position_x + (((label_attributes->last_width - label_attributes->string_width)/2.0) * width_factor); break; case e_label_alignment_right: if ((source.x = d_math_max((label_attributes->string_width-label_attributes->last_width), 0)) == 0) destination.x = position_x + ((label_attributes->last_width - label_attributes->string_width) * width_factor); default: break; } switch (label_attributes->alignment_y) { case e_label_alignment_center: if ((source.y = d_math_max(((label_attributes->string_height-label_attributes->last_height)/2.0), 0)) == 0) destination.y = position_y + (((label_attributes->last_height - label_attributes->string_height)/2.0) * height_factor); break; case e_label_alignment_bottom: if ((source.y = d_math_max((label_attributes->string_height-label_attributes->last_height), 0)) == 0) destination.y = position_y + ((label_attributes->last_height - label_attributes->string_height) * height_factor); default: break; } } else if (label_attributes->format == e_label_background_format_adaptable) { source.w = label_attributes->string_width; source.h = label_attributes->string_height; } destination.w = source.w * width_factor; destination.h = source.h * height_factor; center.x = (position_x + center_x) - destination.x; center.y = (position_y + center_y) - destination.y; label_attributes->last_source = source; label_attributes->last_destination = destination; SDL_RenderCopyEx(environment_attributes->renderer, label_attributes->image, &source, &destination, drawable_attributes->angle, ¢er, (SDL_RendererFlip)drawable_attributes->flip); } d_cast_return(result); }
d_define_method(drawable, get_flags)(struct s_object *self) { d_using(drawable); d_cast_return(drawable_attributes->flags); }
d_define_method(map, find)(struct s_object *self, struct s_object *key) { d_using(map); d_cast_return(f_hash_get(map_attributes->hash, (void *)key)); }