void f_keys_destroy(struct s_list **supplied) { struct s_list_node *entry; while ((entry = (*supplied)->head)) { f_list_delete(*supplied, (struct s_list_node *)entry); d_free(entry); } f_list_destroy(supplied); }
void f_object_delete(struct s_object *object) { struct s_attributes *attributes; struct s_virtual_table *virtual_table; int index; while ((attributes = (struct s_attributes *)object->attributes.tail) && (virtual_table = (struct s_virtual_table *)object->virtual_tables.tail)) { for (index = 0; virtual_table->virtual_table[index].symbol; ++index) if (virtual_table->virtual_table[index].symbol == m_object_delete) { virtual_table->virtual_table[index].method(object, attributes); break; } f_list_delete(&(object->attributes), (struct s_list_node *)attributes); f_list_delete(&(object->virtual_tables), (struct s_list_node *)virtual_table); d_free(attributes); d_free(virtual_table); } if ((object->flags&e_flag_allocated) == e_flag_allocated) d_free(object); }
d_define_method(container, del_drawable)(struct s_object *self, struct s_object *drawable) { d_using(container); struct s_container_drawable *current_container; d_foreach(&(container_attributes->entries), current_container, struct s_container_drawable) if (current_container->drawable == drawable) { f_list_delete(&(container_attributes->entries), (struct s_list_node *)current_container); d_delete(current_container->drawable); d_free(current_container); break; } return self; }
d_define_method_override(illuminable_bitmap, draw)(struct s_object *self, struct s_object *environment) { d_using(illuminable_bitmap); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_lights_emitter_description *lights_emitter; struct s_list affected_lights; struct s_object *result = d_call_owner(self, bitmap, m_drawable_draw, environment); /* recall the father's draw method */ double image_x, image_y, image_center_x, image_center_y, image_principal_point_x, image_principal_point_y, new_x, new_y, radians_rotation = -(drawable_attributes->angle * d_math_radians_conversion), radians_incident, cosine = cos(radians_rotation), sine = sin(radians_rotation), light_normalized_percentage[e_illuminable_bitmap_side_NULL], light_final_mask[e_illuminable_bitmap_side_NULL], local_factor, center_factor, center_factor_reduction; unsigned int index_side; if (illuminable_bitmap_attributes->lights) { memset(&(affected_lights), 0, sizeof(s_list)); for (index_side = 0; index_side < e_illuminable_bitmap_side_NULL; ++index_side) light_final_mask[index_side] = 0; d_call(self, m_drawable_get_scaled_position, &image_x, &image_y); d_call(self, m_drawable_get_scaled_center, &image_center_x, &image_center_y); d_call(self, m_drawable_get_scaled_principal_point, &image_principal_point_x, &image_principal_point_y); d_call(illuminable_bitmap_attributes->lights, m_lights_get_affecting_lights, self, &(affected_lights), environment); d_foreach(&(affected_lights), lights_emitter, struct s_lights_emitter_description) { for (index_side = 0; index_side < e_illuminable_bitmap_side_NULL; ++index_side) light_normalized_percentage[index_side] = 0; /* we need to re-calculate the coordinates of the light in respect of the angle generated by this image */ new_x = lights_emitter->position_x - (image_x + image_center_x); new_y = lights_emitter->position_y - (image_y + image_center_y); lights_emitter->position_x = (new_x * cosine) - (new_y * sine) + (image_x + image_center_x); lights_emitter->position_y = (new_x * sine) + (new_y * cosine) + (image_y + image_center_y); radians_incident = fmod(atan2(lights_emitter->position_y - image_principal_point_y, lights_emitter->position_x - image_principal_point_x), d_math_two_pi); /* we need to convert it to a positive angle */ if (radians_incident < 0) radians_incident = d_math_two_pi + radians_incident; center_factor_reduction = 0.0; switch (illuminable_bitmap_attributes->main_axis) { case e_illuminable_bitmap_axis_x: center_factor = 1.0 - (fabs(lights_emitter->position_x - image_principal_point_x) / ((image_principal_point_x + lights_emitter->radius) - image_x)); if ((intptr_t)d_call(&(drawable_attributes->square_collision_box), m_square_inside_coordinates, lights_emitter->position_x, lights_emitter->position_y)) center_factor_reduction = 1.0 - (fabs(lights_emitter->position_x - image_principal_point_x) / (image_principal_point_x - image_x)); break; case e_illuminable_bitmap_axis_y: center_factor = 1.0 - (fabs(lights_emitter->position_y - image_principal_point_y) / ((image_principal_point_y + lights_emitter->radius) - image_y)); if ((intptr_t)d_call(&(drawable_attributes->square_collision_box), m_square_inside_coordinates, lights_emitter->position_x, lights_emitter->position_y)) center_factor_reduction = 1.0 - (fabs(lights_emitter->position_y - image_principal_point_y) / (image_principal_point_y - image_y)); break; } light_normalized_percentage[e_illuminable_bitmap_side_front] = center_factor; if ((radians_incident >= 0) && (radians_incident < d_math_half_pi)) { light_normalized_percentage[e_illuminable_bitmap_side_bottom] = (radians_incident / d_math_half_pi) * (1.0 - center_factor_reduction); light_normalized_percentage[e_illuminable_bitmap_side_right] = (1.0 - (radians_incident / d_math_half_pi)) * (1.0 - center_factor_reduction); } else if ((radians_incident >= d_math_half_pi) && (radians_incident < d_math_pi)) { light_normalized_percentage[e_illuminable_bitmap_side_left] = ((radians_incident - d_math_half_pi) / d_math_half_pi) * (1.0 - center_factor_reduction); light_normalized_percentage[e_illuminable_bitmap_side_bottom] = (1.0 - ((radians_incident - d_math_half_pi) / d_math_half_pi)) * (1.0 - center_factor_reduction); } else if ((radians_incident >= d_math_pi) && (radians_incident < (d_math_pi + d_math_half_pi))) { light_normalized_percentage[e_illuminable_bitmap_side_top] = ((radians_incident - d_math_pi) / d_math_half_pi) * (1.0 - center_factor_reduction); light_normalized_percentage[e_illuminable_bitmap_side_left] = (1.0 - ((radians_incident - d_math_pi) / d_math_half_pi)) * (1.0 - center_factor_reduction); } else if ((radians_incident >= (d_math_pi + d_math_half_pi)) && (radians_incident < d_math_two_pi)) { light_normalized_percentage[e_illuminable_bitmap_side_right] = ((radians_incident - (d_math_pi + d_math_half_pi)) / d_math_half_pi) * (1.0 - center_factor_reduction); light_normalized_percentage[e_illuminable_bitmap_side_top] = (1.0 - ((radians_incident - (d_math_pi + d_math_half_pi)) / d_math_half_pi)) * (1.0 - center_factor_reduction); } for (index_side = 0; index_side < e_illuminable_bitmap_side_NULL; ++index_side) if ((local_factor = (light_normalized_percentage[index_side] * (((lights_emitter->radius - lights_emitter->distance) / lights_emitter->radius) * 255.0))) > 0) { /* now we have a factor that is proportional with the angle, with the distance and with the radius of the light. What we should do is to normalized * that value using the intensity and the penetration of the light into the */ if ((light_final_mask[index_side] += local_factor) > 255.0) light_final_mask[index_side] = 255.0; } } for (index_side = 0; index_side < e_illuminable_bitmap_side_NULL; ++index_side) { if ((light_final_mask[index_side] > 0) && (illuminable_bitmap_attributes->drawable_mask[index_side])) { /* we don't need to check the visibility because, if we are in this function, means that the visibility of the object has been already confirmed by the * called */ d_call(illuminable_bitmap_attributes->drawable_mask[index_side], m_drawable_set_maskRGB, (unsigned int)light_final_mask[index_side], (unsigned int)light_final_mask[index_side], (unsigned int)light_final_mask[index_side]); while (((intptr_t)d_call(illuminable_bitmap_attributes->drawable_mask[index_side], m_drawable_draw, environment)) == d_drawable_return_continue); } } /* clean the content */ while ((lights_emitter = (struct s_lights_emitter_description *)(affected_lights.head))) { f_list_delete(&(affected_lights), (struct s_list_node *)lights_emitter); d_free(lights_emitter); } }
d_define_method(environment, del_eventable)(struct s_object *self, struct s_object *eventable) { d_using(environment); f_list_delete(&(environment_attributes->eventable), (struct s_list_node *)eventable); return eventable; }
d_define_method(environment, del_drawable)(struct s_object *self, struct s_object *drawable, int layer, enum e_environment_surfaces surface) { d_using(environment); f_list_delete(&(environment_attributes->drawable[surface][layer]), (struct s_list_node *)drawable); return drawable; }