#include #include #include #include "Aw.h" /** * Creates and initializes a new mover structure. * * The initialized structure must be manually destroyed using free(). * The remaining fields of the mover are to be set by yourself. * * The value NULL may be specified for any string field to indicate * that a string is not to be assigned. * * Waypoints are not set by this function. To add or remove waypoints, * use the mover_waypoint_add and mover_waypoint_del functions. * * @param name Mover's tag name * @param seq SEQ filename * @param script (Unknown... What is this?) * @param sound Sound filename * @param bump_name Detach on bump * @return An initialized aw_object_data_mover structure. */ aw_object_data_mover* new_mover(const char* name, const char* seq, const char* script, const char* sound, const char* bump_name) { size_t n_len = (name == NULL)? 0 : strlen(name); size_t q_len = (seq == NULL)? 0 : strlen(seq); size_t r_len = (script == NULL)? 0 : strlen(script); size_t s_len = (sound == NULL)? 0 : strlen(sound); size_t b_len = (bump_name == NULL)? 0 : strlen(bump_name); size_t psiz = n_len + q_len + r_len + s_len + b_len + sizeof(aw_object_data_mover); aw_object_data_mover* mov = NULL; mov = (aw_object_data_mover*)malloc(psiz); memset(mov, 0, psiz); mov->name_len = (unsigned char)n_len; mov->seq_len = (unsigned char)q_len; mov->script_len = (unsigned char)r_len; mov->sound_len = (unsigned char)s_len; mov->bump_name_len = (unsigned char)b_len; if (n_len != 0) memcpy(mov->str_data, name, n_len); if (q_len != 0) memcpy(mov->str_data + n_len, seq, q_len); if (r_len != 0) memcpy(mov->str_data + n_len + q_len, sound, r_len); if (s_len != 0) memcpy(mov->str_data + n_len + q_len + r_len, sound, s_len); if (b_len != 0) memcpy(mov->str_data + n_len + q_len + r_len + s_len, bump_name, b_len); mov->type = AW_MOVER_TYPE_ACTIVE; /* 'User Controlled' */ return mov; } /** * Determine the total size of a mover structure. */ unsigned int sizeof_mover(const aw_object_data_mover* mov) { unsigned int siz = 0; siz = sizeof(aw_object_data_mover); siz += mov->name_len; siz += mov->seq_len; siz += mov->script_len; siz += mov->sound_len; siz += mov->waypoints_len; siz += mov->bump_name_len; return siz; } /** * Prepares an initialized mover structure to be built in the world. * * After calling this function use either the aw_object_add or * aw_object_load SDK methods after setting additional attributes * defining the location, etc. * * @param mov The object to be built. */ void prepare_mover(const aw_object_data_mover* mov) { aw_string_set(AW_OBJECT_DESCRIPTION, ""); aw_string_set(AW_OBJECT_ACTION, ""); aw_int_set(AW_OBJECT_TYPE, AW_OBJECT_TYPE_MOVER); aw_data_set(AW_OBJECT_DATA, (char*)(mov), sizeof_mover(mov)); } /** * Determine the name of a mover, and copy it to the specified * buffer. * * If the buffer is too small to copy the string, a negative value * is returned specifying the number of additional bytes needed * to completely copy the string. * * @param dst Buffer to receive the string. * @param src Object to retrieve string from. * @param max Maximum size of the buffer, including NUL terminator. * @return Length of string, or zero if not set. */ int mover_get_name(char* dst, const aw_object_data_mover* src, size_t max) { if (src->name_len == 0) return 0; if ((size_t)(src->name_len) >= max) { int bytes = (int)src->name_len - (int)max; return (0 - bytes); } memset(dst, 0, max); memcpy(dst, src->str_data, src->name_len); return (int)(src->name_len); } /** * Add a waypoint to the mover. */ void mover_waypoint_add(aw_object_data_mover** pmov, const aw_waypoint* point) { aw_object_data_mover* mov = *pmov; size_t psiz = 0; size_t movsiz = sizeof_mover(mov); size_t cursiz = 0; char* curpoints = NULL; size_t w_len = 0; char* newpoints = NULL; size_t nd_siz = 0; char* new_data = NULL; /* Figure out the current size and waypoints */ cursiz = (size_t)(mov->waypoints_len); curpoints = mov->str_data + (mov->name_len + mov->seq_len + mov->script_len + mov->sound_len); /* Now figure out the new size */ w_len = cursiz + sizeof(aw_waypoint); newpoints = (char*)malloc(w_len); /* Copy old waypoints then add the new one */ if (cursiz != 0) memcpy(newpoints, curpoints, w_len); memcpy(newpoints + cursiz, point, sizeof(aw_waypoint)); /* Reinitialize the structure's string area */ /* This should NOT affect other fields */ psiz = (movsiz - cursiz) + w_len; mov = (aw_object_data_mover*)realloc(mov, psiz); /* Rebuild string data */ mov->waypoints_len = (unsigned short)(w_len); nd_siz = ((movsiz - sizeof(aw_object_data_mover)) - cursiz) + w_len; new_data = (char*)malloc(nd_siz); memset(new_data, 0, nd_siz); memcpy(new_data, mov->str_data, mov->name_len + mov->seq_len + mov->script_len + mov->sound_len); memcpy(new_data + mov->name_len + mov->seq_len + mov->script_len + mov->sound_len, newpoints, mov->waypoints_len); free(newpoints); if (mov->bump_name_len != 0) memcpy(new_data + mov->name_len + mov->seq_len + mov->script_len + mov->sound_len + mov->waypoints_len, mov->str_data + mov->name_len + mov->seq_len + mov->script_len + mov->sound_len + mov->waypoints_len, mov->bump_name_len); memcpy(mov->str_data, new_data, nd_siz); free(new_data); *pmov = mov; } /** * Determine the number of waypoints in a mover. */ int mover_count_waypoints(const aw_object_data_mover* mov) { return (int)(mov->waypoints_len) / sizeof(aw_waypoint); } /** * Retrieve all waypoints from a mover. * * @param count Pointer to an integer which will receive the number * of waypoints. * @param mov Mover to retrieve waypoints from. * @return An array of aw_waypoint structures, or NULL if the mover * has no waypoints. */ aw_waypoint* mover_get_waypoints(int* count, const aw_object_data_mover* mov) { if (mov->waypoints_len == 0) return NULL; *count = (int)(mov->waypoints_len) / sizeof(aw_waypoint); return (aw_waypoint*)(mov->str_data + (mov->name_len + mov->seq_len + mov->script_len + mov->sound_len)); } /** * Retrieve a single waypoint from a mover. * * @param num Index of waypoint to retrieve. * @param mov Mover to retrieve waypoint from. */ aw_waypoint* mover_get_waypoint(const int num, const aw_object_data_mover* mov) { int max = 0; aw_waypoint* pts = mover_get_waypoints(&max, mov); if (num >= max) return NULL; return &pts[num]; }