int el_read_float(el_file_ptr file, float *f) { if (file->current + sizeof(float) > file->end) return 0; #ifdef EL_FORCE_ALIGNED_READ { float tmp; memcpy(&tmp, file->current, sizeof(float)); *f = SwapLEFloat(tmp); } #else *f = SwapLEFloat(*((float*)file->current)); #endif file->current += sizeof(float); return 1; }
int get_3d_objects_from_server (int nr_objs, const Uint8 *data, int len) { int iobj; int obj_x, obj_y; int offset, nb_left; float x = 0.0f, y = 0.0f, z = 0.0f, rx = 0.0f, ry = 0.0f, rz = 0.0f; char obj_name[128]; int name_len, max_name_len; int id = -1; int all_ok = 1; offset = 0; nb_left = len; for (iobj = 0; iobj < nr_objs; iobj++) { int obj_err = 0; if (nb_left < 14) { // Warn about this error! LOG_WARNING("Incomplete 3D objects list!"); all_ok = 0; break; } obj_x = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; obj_y = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; if (obj_x > tile_map_size_x * 6 || obj_y > tile_map_size_y * 6) { // Warn about this error! LOG_WARNING("A 3D object was located OUTSIDE the map!"); offset += 8; obj_err = 1; } else { rx = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; ry = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; rz = SwapLEFloat (*((float *)(&data[offset]))); offset += 2; id = SDL_SwapLE16 (*((Uint16 *)(&data[offset]))); offset += 2; x = 0.5f * obj_x + 0.25f; y = 0.5f * obj_y + 0.25f; z = get_tile_height(obj_x, obj_y); } nb_left -= 12; max_name_len = nb_left > sizeof (obj_name) ? sizeof (obj_name) : nb_left; name_len = safe_snprintf (obj_name, max_name_len, "%s", &data[offset]); if (name_len < 0 || name_len >= sizeof (obj_name)) { // Warn about this error! LOG_WARNING("3D object has invalid or too long file name!"); all_ok = 0; break; } offset += name_len + 1; nb_left -= name_len + 1; if (!obj_err) add_e3d_at_id (id, obj_name, x, y, z, rx, ry, rz, 0, 0, 1.0f, 1.0f, 1.0f, 1); else all_ok = 0; } return all_ok; }
static void read_vertex_buffer(el_file_ptr file, float* buffer, const Uint32 vertex_count, const Uint32 vertex_size, const Uint32 options, const Uint32 format) { float temp[3]; Uint16 tmp[3]; Uint32 i, idx, offset; Uint8 color[4]; idx = 0; offset = el_tell(file); for (i = 0; i < vertex_count; i++) { el_seek(file, offset + i * vertex_size, SEEK_SET); if (half_uv(format)) { el_read(file, 2 * sizeof(Uint16), tmp); temp[0] = half_to_float(SDL_SwapLE16(tmp[0])); temp[1] = half_to_float(SDL_SwapLE16(tmp[1])); } else { el_read(file, 2 * sizeof(float), temp); temp[0] = SwapLEFloat(temp[0]); temp[1] = SwapLEFloat(temp[1]); } buffer[idx + 0] = temp[0]; buffer[idx + 1] = temp[1]; idx += 2; if (has_secondary_texture_coordinate(options)) { if (half_extra_uv(format)) { el_seek(file, 2 * sizeof(Uint16), SEEK_CUR); } else { el_seek(file, 2 * sizeof(float), SEEK_CUR); } } if (has_normal(options)) { if (compressed_normal(format)) { el_read(file, sizeof(Uint16), tmp); uncompress_normal(SDL_SwapLE16(tmp[0]), temp); } else { el_read(file, 3 * sizeof(float), temp); temp[0] = SwapLEFloat(temp[0]); temp[1] = SwapLEFloat(temp[1]); temp[2] = SwapLEFloat(temp[2]); } buffer[idx + 0] = temp[0]; buffer[idx + 1] = temp[1]; buffer[idx + 2] = temp[2]; idx += 3; } if (has_tangent(options)) { if (compressed_normal(format)) { el_seek(file, sizeof(Uint16), SEEK_CUR); } else { el_seek(file, 3 * sizeof(float), SEEK_CUR); } } if (half_position(format)) { el_read(file, 3 * sizeof(Uint16), tmp); temp[0] = half_to_float(SDL_SwapLE16(tmp[0])); temp[1] = half_to_float(SDL_SwapLE16(tmp[1])); temp[2] = half_to_float(SDL_SwapLE16(tmp[2])); } else { el_read(file, 3 * sizeof(float), temp); temp[0] = SwapLEFloat(temp[0]); temp[1] = SwapLEFloat(temp[1]); temp[2] = SwapLEFloat(temp[2]); } buffer[idx + 0] = temp[0]; buffer[idx + 1] = temp[1]; buffer[idx + 2] = temp[2]; idx += 3; if (has_color(options)) { el_read(file, 4 * sizeof(Uint8), color); memcpy(&buffer[idx], color, 4 * sizeof(Uint8)); idx += 1; } } }
static e3d_object* do_load_e3d_detail(e3d_object* cur_object) { e3d_header header; e3d_material material; char cur_dir[1024]; int i, idx, l, mem_size, vertex_size, material_size; int file_pos, indices_size, index_size; char text_file_name[1024]; Uint32 tmp; Uint16 tmp_16; Uint8* index_pointer; el_file_ptr file; version_number version; if (cur_object == 0) return 0; memset(cur_dir, 0, sizeof(cur_dir)); //get the current directory l = strlen(cur_object->file_name); //parse the string backwards, until we find a / while (l > 0) { if ((cur_object->file_name[l] == '/') || (cur_object->file_name[l] == '\\')) break; l--; } i = 0; if (l)//prevent invalid dir names { while (l >= 0) { cur_dir[i] = cur_object->file_name[i]; i++; l--; } cur_dir[i+1] = 0; } LOG_DEBUG_OLD("Loading e3d file '%s'.", cur_object->file_name); file = el_open(cur_object->file_name); if (file == 0) { LOG_ERROR_OLD("Can't open file '%s'!", cur_object->file_name); free_e3d_pointer(cur_object); return 0; } if (read_and_check_elc_header(file, EL3D_FILE_MAGIC_NUMBER, &version, cur_object->file_name) != 0) { LOG_ERROR_OLD("File '%s' has wrong header!", cur_object->file_name); free_e3d_pointer(cur_object); el_close(file); return 0; } el_read(file, sizeof(e3d_header), &header); cur_object->vertex_no = SDL_SwapLE32(header.vertex_no); cur_object->index_no = SDL_SwapLE32(header.index_no); cur_object->material_no = SDL_SwapLE32(header.material_no); vertex_size = SDL_SwapLE32(header.vertex_size); material_size = SDL_SwapLE32(header.material_size); index_size = SDL_SwapLE32(header.index_size); LOG_DEBUG_OLD("E3d file vertex count %d and size %d.", cur_object->vertex_no, vertex_size); LOG_DEBUG_OLD("E3d file index count %d and size %d.", cur_object->index_no, index_size); LOG_DEBUG_OLD("E3d file material count %d and size %d.", cur_object->material_no, material_size); LOG_DEBUG_OLD("E3d file version %d.%d.%d.%d.", version[0], version[1], version[2], version[3]); if ((version[0] == 1) && (version[1] == 1)) { if ((header.vertex_options & 0xF0) != 0) { LOG_ERROR_OLD("Unknow options (%d) for file %s.", header.vertex_options, cur_object->file_name); } header.vertex_options &= 0x0F; if ((header.vertex_format & 0xE0) != 0) { LOG_ERROR_OLD("Unknow format (%d) for file %s.", header.vertex_format, cur_object->file_name); } header.vertex_format &= 0x1F; } else { if ((version[0] == 1) && (version[1] == 0)) { header.vertex_format = 0; header.vertex_options ^= 0x01; header.vertex_options &= 0x07; } else { LOG_ERROR_OLD("File '%s' has wrong version number!", cur_object->file_name); free_e3d_pointer(cur_object); el_close(file); return 0; } } idx = 0; if (has_normal(header.vertex_options)) { idx += 1; } if (has_color(header.vertex_options)) { idx += 2; } cur_object->vertex_layout = &(vertex_layout_array[idx]); // They have at least the size we expected if (check_vertex_size(vertex_size, header.vertex_options, header.vertex_format) == 0) { LOG_ERROR_OLD("File '%s' has wrong vertex size!", cur_object->file_name); free_e3d_pointer(cur_object); el_close(file); return 0; } if (material_size != get_material_size(header.vertex_options)) { LOG_ERROR_OLD("File '%s' has wrong material size! Expected size %d, found size %d.", cur_object->file_name, get_material_size(header.vertex_options), material_size); free_e3d_pointer(cur_object); el_close(file); return 0; } if (short_index(header.vertex_format)) { if (index_size != sizeof(Uint16)) { LOG_ERROR_OLD("File '%s' has wrong index size! Expected size %d, found size %d.", cur_object->file_name, sizeof(Uint16), index_size); free_e3d_pointer(cur_object); el_close(file); return 0; } } else { if (index_size != sizeof(Uint32)) { LOG_ERROR_OLD("File '%s' has wrong index size! Expected size %d, found size %d.", cur_object->file_name, sizeof(Uint32), index_size); free_e3d_pointer(cur_object); el_close(file); return 0; } } LOG_DEBUG_OLD("Reading vertices at %d from e3d file '%s'.", SDL_SwapLE32(header.vertex_offset), cur_object->file_name); // Now reading the vertices el_seek(file, SDL_SwapLE32(header.vertex_offset), SEEK_SET); cur_object->vertex_data = malloc(cur_object->vertex_no * cur_object->vertex_layout->size); mem_size = cur_object->vertex_no * cur_object->vertex_layout->size; if (!CHECK_POINTER(cur_object->vertex_data, "vertex data")) return 0; read_vertex_buffer(file, (float*)(cur_object->vertex_data), cur_object->vertex_no, vertex_size, header.vertex_options, header.vertex_format); LOG_DEBUG_OLD("Reading indices at %d from e3d file '%s'.", SDL_SwapLE32(header.index_offset), cur_object->file_name); // Now reading the indices el_seek(file, SDL_SwapLE32(header.index_offset), SEEK_SET); if (cur_object->index_no < 65536) { indices_size = 2; cur_object->index_type = GL_UNSIGNED_SHORT; } else { indices_size = 4; cur_object->index_type = GL_UNSIGNED_INT; } cur_object->indices = malloc(cur_object->index_no * indices_size); index_pointer = 0; for (i = 0; i < cur_object->index_no; i++) { if (index_size == 2) { el_read(file, sizeof(Uint16), &tmp_16); tmp = SDL_SwapLE16(tmp_16); } else { el_read(file, sizeof(Uint32), &tmp); tmp = SDL_SwapLE32(tmp); } if (indices_size == 2) { ((Uint16*)(cur_object->indices))[i] = tmp; } else { ((Uint32*)(cur_object->indices))[i] = tmp; } } // only allocate the materials structure if it doesn't exist (on initial load) if (cur_object->materials == 0) { cur_object->materials = (e3d_draw_list*)malloc(cur_object->material_no*sizeof(e3d_draw_list)); if (!CHECK_POINTER(cur_object->materials, "materials")) return 0; memset(cur_object->materials, 0, cur_object->material_no * sizeof(e3d_draw_list)); } mem_size += cur_object->material_no * sizeof(e3d_draw_list); LOG_DEBUG_OLD("Reading materials at %d from e3d file '%s'.", SDL_SwapLE32(header.material_offset), cur_object->file_name); // Now reading the materials el_seek(file, SDL_SwapLE32(header.material_offset), SEEK_SET); cur_object->min_x = 1e10f; cur_object->min_y = 1e10f; cur_object->min_z = 1e10f; cur_object->max_x = -1e10f; cur_object->max_y = -1e10f; cur_object->max_z = -1e10f; cur_object->max_size = -1e10f; for (i = 0; i < cur_object->material_no; i++) { file_pos = el_tell(file); el_read(file, sizeof(e3d_material), &material); safe_snprintf(text_file_name, sizeof(text_file_name), "%s%s", cur_dir, material.material_name); cur_object->materials[i].options = SDL_SwapLE32(material.options); #ifdef MAP_EDITOR #ifdef NEW_TEXTURES cur_object->materials[i].texture = load_texture_cached(text_file_name, tt_mesh); #else /* NEW_TEXTURES */ cur_object->materials[i].texture = load_texture_cache(text_file_name,0); #endif /* NEW_TEXTURES */ #else //MAP_EDITOR #ifdef NEW_TEXTURES cur_object->materials[i].texture = load_texture_cached(text_file_name, tt_mesh); #else /* NEW_TEXTURES */ #ifdef NEW_ALPHA // prepare to load the textures depending on if it is transparent or not (diff alpha handling) if (material_is_transparent(cur_object->materials[i].options)) { // is this object transparent? cur_object->materials[i].texture= load_texture_cache_deferred(text_file_name, -1); } else { cur_object->materials[i].texture= load_texture_cache_deferred(text_file_name, -1); //255); } #else //NEW_ALPHA // cur_object->materials[i].texture = load_texture_cache_deferred(text_file_name, 255); cur_object->materials[i].texture = load_texture_cache_deferred(text_file_name, 0); #endif //NEW_ALPHA #endif /* NEW_TEXTURES */ #endif //MAP_EDITOR cur_object->materials[i].min_x = SwapLEFloat(material.min_x); cur_object->materials[i].min_y = SwapLEFloat(material.min_y); cur_object->materials[i].min_z = SwapLEFloat(material.min_z); cur_object->materials[i].max_x = SwapLEFloat(material.max_x); cur_object->materials[i].max_y = SwapLEFloat(material.max_y); cur_object->materials[i].max_z = SwapLEFloat(material.max_z); // calculate the max size for cruse LOD processing cur_object->materials[i].max_size= max2f(max2f(cur_object->materials[i].max_x-cur_object->materials[i].min_x, cur_object->materials[i].max_y-cur_object->materials[i].min_y), cur_object->materials[i].max_z-cur_object->materials[i].min_z); cur_object->min_x = min2f(cur_object->min_x, cur_object->materials[i].min_x); cur_object->min_y = min2f(cur_object->min_y, cur_object->materials[i].min_y); cur_object->min_z = min2f(cur_object->min_z, cur_object->materials[i].min_z); cur_object->max_x = max2f(cur_object->max_x, cur_object->materials[i].max_x); cur_object->max_y = max2f(cur_object->max_y, cur_object->materials[i].max_y); cur_object->max_z = max2f(cur_object->max_z, cur_object->materials[i].max_z); cur_object->max_size = max2f(cur_object->max_size, cur_object->materials[i].max_size); cur_object->materials[i].triangles_indices_index = indices_size*SDL_SwapLE32(material.index) + index_pointer; cur_object->materials[i].triangles_indices_count = SDL_SwapLE32(material.count); cur_object->materials[i].triangles_indices_min = SDL_SwapLE32(material.triangles_min_index); cur_object->materials[i].triangles_indices_max = SDL_SwapLE32(material.triangles_max_index); file_pos += SDL_SwapLE32(material_size); el_seek(file, file_pos, SEEK_SET); } el_close(file); LOG_DEBUG_OLD("Building vertex buffers for e3d file '%s'.", cur_object->file_name); //Generate the buffers glGenBuffersARB(1, &cur_object->vertex_vbo); glBindBufferARB(GL_ARRAY_BUFFER_ARB, cur_object->vertex_vbo); glBufferDataARB(GL_ARRAY_BUFFER_ARB, cur_object->vertex_no * cur_object->vertex_layout->size, cur_object->vertex_data, GL_STATIC_DRAW_ARB); #ifndef MAP_EDITOR free(cur_object->vertex_data); cur_object->vertex_data = 0; #endif //MAP_EDITOR glGenBuffersARB(1, &cur_object->indices_vbo); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, cur_object->indices_vbo); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, cur_object->index_no * indices_size, cur_object->indices, GL_STATIC_DRAW_ARB); #ifndef MAP_EDITOR free(cur_object->indices); cur_object->indices = 0; #endif //MAP_EDITOR glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); #ifndef MAP_EDITOR LOG_DEBUG_OLD("Adding e3d file '%s' to cache.", cur_object->file_name); cache_adj_size(cache_e3d, mem_size, cur_object); #endif //MAP_EDITOR return cur_object; }
static int do_load_map(const char *file_name, update_func *update_function) { int i; int cur_tile, j; AABBOX bbox; map_header cur_map_header; char* file_mem; #ifdef CLUSTER_INSIDES char* occupied = 0; int have_clusters; #endif object3d_io* objs_3d; obj_2d_io* objs_2d; light_io* lights; particles_io* particles; #ifndef FASTER_MAP_LOAD float progress; #endif el_file_ptr file; file = el_open(file_name); if (!file) { return 0; } #ifdef EXTRA_DEBUG ERR(); #endif file_mem = el_get_pointer(file); my_strcp(map_file_name, file_name); LOG_DEBUG("Loading map '%s'.", file_name); main_bbox_tree_items = create_bbox_items(1024); memcpy(&cur_map_header, file_mem, sizeof(cur_map_header)); cur_map_header.tile_map_x_len = SDL_SwapLE32(cur_map_header.tile_map_x_len); cur_map_header.tile_map_y_len = SDL_SwapLE32(cur_map_header.tile_map_y_len); cur_map_header.tile_map_offset = SDL_SwapLE32(cur_map_header.tile_map_offset); cur_map_header.height_map_offset = SDL_SwapLE32(cur_map_header.height_map_offset); cur_map_header.obj_3d_struct_len = SDL_SwapLE32(cur_map_header.obj_3d_struct_len); cur_map_header.obj_3d_no = SDL_SwapLE32(cur_map_header.obj_3d_no); cur_map_header.obj_3d_offset = SDL_SwapLE32(cur_map_header.obj_3d_offset); cur_map_header.obj_2d_struct_len = SDL_SwapLE32(cur_map_header.obj_2d_struct_len); cur_map_header.obj_2d_no = SDL_SwapLE32(cur_map_header.obj_2d_no); cur_map_header.obj_2d_offset = SDL_SwapLE32(cur_map_header.obj_2d_offset); cur_map_header.lights_struct_len = SDL_SwapLE32(cur_map_header.lights_struct_len); cur_map_header.lights_no = SDL_SwapLE32(cur_map_header.lights_no); cur_map_header.lights_offset = SDL_SwapLE32(cur_map_header.lights_offset); cur_map_header.ambient_r = SwapLEFloat(cur_map_header.ambient_r); cur_map_header.ambient_g = SwapLEFloat(cur_map_header.ambient_g); cur_map_header.ambient_b = SwapLEFloat(cur_map_header.ambient_b); cur_map_header.particles_struct_len = SDL_SwapLE32(cur_map_header.particles_struct_len); cur_map_header.particles_no = SDL_SwapLE32(cur_map_header.particles_no); cur_map_header.particles_offset = SDL_SwapLE32(cur_map_header.particles_offset); #ifdef CLUSTER_INSIDES cur_map_header.clusters_offset = SDL_SwapLE32(cur_map_header.clusters_offset); #endif LOG_DEBUG("Checking map '%s' file signature.", file_name); //verify if we have a valid file if(cur_map_header.file_sig[0]!='e'|| cur_map_header.file_sig[1]!='l'|| cur_map_header.file_sig[2]!='m'|| cur_map_header.file_sig[3]!='f') { LOG_ERROR(invalid_map, map_file_name); exit_now = 1; // We might as well quit... el_close(file); return 0; } LOG_DEBUG("Checking map '%s' sizes.", file_name); // Check the sizes of structures. If they don't match, we have a // major problem, since these structures are supposed to be // written flat out to disk. if (cur_map_header.obj_3d_struct_len != sizeof (object3d_io) || cur_map_header.obj_2d_struct_len != sizeof (obj_2d_io) || cur_map_header.lights_struct_len != sizeof (light_io) || (cur_map_header.particles_struct_len != sizeof (particles_io) && cur_map_header.particles_no > 0) ) { LOG_ERROR ("Invalid object size on map %s", map_file_name); exit_now = 1; // We might as well quit... el_close(file); return 0; } update_function(load_map_str, 0); //get the map size tile_map_size_x = cur_map_header.tile_map_x_len; tile_map_size_y = cur_map_header.tile_map_y_len; LOG_DEBUG("Map '%s' size <%d, %d>.", file_name, tile_map_size_x, tile_map_size_y); // allocate the tile map (it was destroyed), and fill it tile_map = calloc (tile_map_size_x*tile_map_size_y, 1); memcpy(tile_map, file_mem + cur_map_header.tile_map_offset, tile_map_size_x*tile_map_size_y); begin_managing_memchunk(tile_map); // allocate the height map, and fill it height_map = calloc (tile_map_size_x*tile_map_size_y*6*6, 1); memcpy(height_map, file_mem + cur_map_header.height_map_offset, tile_map_size_x*tile_map_size_y*6*6); begin_managing_memchunk(height_map); #ifdef CLUSTER_INSIDES // check if we need to compute the clusters, or if they're stored // in the map have_clusters = (cur_map_header.clusters_offset > 0) && ((cur_map_header.clusters_offset + tile_map_size_x * tile_map_size_y * 6 * 6 * sizeof(short)) <= el_get_size(file)); LOG_DEBUG("Map '%s' has clusters: %d.", file_name, have_clusters); if (have_clusters) { // clusters are stored in the map, set them set_clusters (file_mem + cur_map_header.clusters_offset); } else { // We need to compute the clusters, allocate memory for // the occupation array, and initialize it with the // tile and height maps occupied = calloc (tile_map_size_x*tile_map_size_y*6*6, 1); update_occupied_with_tile_map (occupied, tile_map); update_occupied_with_height_map (occupied, height_map); } #endif LOG_DEBUG("Map '%s' is dungeon %d and ambient <%f, %f, %f>.", file_name, cur_map_header.dungeon, cur_map_header.ambient_r, cur_map_header.ambient_g, cur_map_header.ambient_b); //get the type of map, and the ambient light dungeon = cur_map_header.dungeon; ambient_r = cur_map_header.ambient_r; ambient_g = cur_map_header.ambient_g; ambient_b = cur_map_header.ambient_b; /* water_tiles_extension = (tile_map_size_x > tile_map_size_y ? */ /* tile_map_size_x : tile_map_size_y * 1.5); */ /* if (water_tiles_extension < 500.0) */ /* water_tiles_extension = 500.0 - water_tiles_extension; */ /* else */ /* water_tiles_extension = 0.0; */ LOG_DEBUG("Loading tiles"); //load the tiles in this map, if not already loaded load_map_tiles(); LOG_DEBUG("Initializing buffers"); init_buffers(); #ifndef CLUSTER_INSIDES for(i = 0; i < tile_map_size_y; i++) { bbox.bbmin[Y] = i*3.0f; bbox.bbmax[Y] = (i+1)*3.0f; if (i == 0) bbox.bbmin[Y] -= water_tiles_extension; else if (i == tile_map_size_y-1) bbox.bbmax[Y] += water_tiles_extension; for(j = 0; j < tile_map_size_x; j++) { cur_tile = tile_map[i*tile_map_size_x+j]; if (cur_tile != 255) { bbox.bbmin[X] = j*3.0f; bbox.bbmax[X] = (j+1)*3.0f; if (j == 0) bbox.bbmin[X] -= water_tiles_extension; else if (j == tile_map_size_x-1) bbox.bbmax[X] += water_tiles_extension; if (IS_WATER_TILE(cur_tile)) { bbox.bbmin[Z] = -0.25f; bbox.bbmax[Z] = -0.25f; if (IS_REFLECTING(cur_tile)) add_water_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile, 1); else add_water_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile, 0); } else { bbox.bbmin[Z] = 0.0f; bbox.bbmax[Z] = 0.0f; add_terrain_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile); } } } } #endif // CLUSTER_INSIDES #ifdef FASTER_MAP_LOAD update_function(load_3d_object_str, 20.0f); #else // FASTER_MAP_LOAD progress = (cur_map_header.obj_3d_no + 249) / 250; if (progress > 0.0f) { update_function(load_3d_object_str, 0.0f); progress = 20.0f / progress; } else { update_function(load_3d_object_str, 20.0f); progress = 0.0f; } #endif // FASTER_MAP_LOAD LOG_DEBUG("Loading %d 3d objects.", cur_map_header.obj_3d_no); //read the 3d objects #ifndef FASTER_MAP_LOAD clear_objects_list_placeholders(); #endif objs_3d = (object3d_io*) (file_mem + cur_map_header.obj_3d_offset); ENTER_DEBUG_MARK("load 3d objects"); for (i = 0; i < cur_map_header.obj_3d_no; i++) { object3d_io cur_3d_obj_io = objs_3d[i]; cur_3d_obj_io.x_pos = SwapLEFloat (cur_3d_obj_io.x_pos); cur_3d_obj_io.y_pos = SwapLEFloat (cur_3d_obj_io.y_pos); cur_3d_obj_io.z_pos = SwapLEFloat (cur_3d_obj_io.z_pos); cur_3d_obj_io.x_rot = SwapLEFloat (cur_3d_obj_io.x_rot); cur_3d_obj_io.y_rot = SwapLEFloat (cur_3d_obj_io.y_rot); cur_3d_obj_io.z_rot = SwapLEFloat (cur_3d_obj_io.z_rot); cur_3d_obj_io.r = SwapLEFloat (cur_3d_obj_io.r); cur_3d_obj_io.g = SwapLEFloat (cur_3d_obj_io.g); cur_3d_obj_io.b = SwapLEFloat (cur_3d_obj_io.b); LOG_DEBUG("Adding 3d object (%d) '%s' at <%d, %f, %f> with " "rotation <%f, %f, %f>, left lit %d, blended %d and " "color <%f, %f, %f>.", i, cur_3d_obj_io.file_name, cur_3d_obj_io.x_pos, cur_3d_obj_io.y_pos, cur_3d_obj_io.z_pos, cur_3d_obj_io.x_rot, cur_3d_obj_io.y_rot, cur_3d_obj_io.z_rot, cur_3d_obj_io.self_lit, cur_3d_obj_io.blended, cur_3d_obj_io.r, cur_3d_obj_io.g, cur_3d_obj_io.b); if (cur_3d_obj_io.blended != 20) { #ifdef CLUSTER_INSIDES int id; if (cur_3d_obj_io.blended != 1) cur_3d_obj_io.blended = 0; id = add_e3d (cur_3d_obj_io.file_name, cur_3d_obj_io.x_pos, cur_3d_obj_io.y_pos, cur_3d_obj_io.z_pos, cur_3d_obj_io.x_rot, cur_3d_obj_io.y_rot, cur_3d_obj_io.z_rot, cur_3d_obj_io.self_lit, cur_3d_obj_io.blended, cur_3d_obj_io.r, cur_3d_obj_io.g, cur_3d_obj_io.b, 0); if (!have_clusters) update_occupied_with_3d (occupied, id); #else if (cur_3d_obj_io.blended != 1) cur_3d_obj_io.blended = 0; add_e3d (cur_3d_obj_io.file_name, cur_3d_obj_io.x_pos, cur_3d_obj_io.y_pos, cur_3d_obj_io.z_pos, cur_3d_obj_io.x_rot, cur_3d_obj_io.y_rot, cur_3d_obj_io.z_rot, cur_3d_obj_io.self_lit, cur_3d_obj_io.blended, cur_3d_obj_io.r, cur_3d_obj_io.g, cur_3d_obj_io.b, 0); #endif } else { inc_objects_list_placeholders(); } #ifndef FASTER_MAP_LOAD if (i % 250 == 0) { update_function(load_3d_object_str, progress); } #endif } LEAVE_DEBUG_MARK("load 3d objects"); #ifdef FASTER_MAP_LOAD update_function(load_2d_object_str, 20.0f); #else // FASTER_MAP_LOAD progress = (cur_map_header.obj_2d_no + 249) / 250; if (progress > 0) { update_function(load_2d_object_str, 0.0f); progress = 20.0f / progress; } else { update_function(load_2d_object_str, 20.0f); progress = 0.0f; } #endif // FASTER_MAP_LOAD LOG_DEBUG("Loading %d 2d objects.", cur_map_header.obj_2d_no); //read the 2d objects objs_2d = (obj_2d_io*) (file_mem + cur_map_header.obj_2d_offset); ENTER_DEBUG_MARK("load 2d objects"); for (i = 0; i < cur_map_header.obj_2d_no; i++) { obj_2d_io cur_2d_obj_io = objs_2d[i]; #ifdef CLUSTER_INSIDES int id; #endif cur_2d_obj_io.x_pos = SwapLEFloat(cur_2d_obj_io.x_pos); cur_2d_obj_io.y_pos = SwapLEFloat(cur_2d_obj_io.y_pos); cur_2d_obj_io.z_pos = SwapLEFloat(cur_2d_obj_io.z_pos); cur_2d_obj_io.x_rot = SwapLEFloat(cur_2d_obj_io.x_rot); cur_2d_obj_io.y_rot = SwapLEFloat(cur_2d_obj_io.y_rot); cur_2d_obj_io.z_rot = SwapLEFloat(cur_2d_obj_io.z_rot); LOG_DEBUG("Adding 2d object (%d) '%s' at <%d, %f, %f> with " "rotation <%f, %f, %f>.", i, cur_2d_obj_io.file_name, cur_2d_obj_io.x_pos, cur_2d_obj_io.y_pos, cur_2d_obj_io.z_pos, cur_2d_obj_io.x_rot, cur_2d_obj_io.y_rot, cur_2d_obj_io.z_rot); #ifndef SHOW_FLICKERING // Add in low-order bits to prevent flicker. cur_2d_obj_io.z_pos += offset_2d; offset_2d += offset_2d_increment; if (offset_2d >= offset_2d_max) offset_2d = offset_2d_increment; #endif #ifdef FASTER_MAP_LOAD #ifdef CLUSTER_INSIDES id = add_2d_obj(i, cur_2d_obj_io.file_name, cur_2d_obj_io.x_pos, cur_2d_obj_io.y_pos, cur_2d_obj_io.z_pos, cur_2d_obj_io.x_rot, cur_2d_obj_io.y_rot, cur_2d_obj_io.z_rot, 0); if (!have_clusters) update_occupied_with_2d (occupied, id); #else // CLUSTER_INSIDES add_2d_obj(i, cur_2d_obj_io.file_name, cur_2d_obj_io.x_pos, cur_2d_obj_io.y_pos, cur_2d_obj_io.z_pos, cur_2d_obj_io.x_rot, cur_2d_obj_io.y_rot, cur_2d_obj_io.z_rot, 0); #endif // CLUSTER_INSIDES #else // FASTER_MAP_LOAD #ifdef CLUSTER_INSIDES id = add_2d_obj (cur_2d_obj_io.file_name, cur_2d_obj_io.x_pos, cur_2d_obj_io.y_pos, cur_2d_obj_io.z_pos, cur_2d_obj_io.x_rot, cur_2d_obj_io.y_rot, cur_2d_obj_io.z_rot, 0); if (!have_clusters) update_occupied_with_2d (occupied, id); #else // CLUSTER_INSIDES add_2d_obj(cur_2d_obj_io.file_name, cur_2d_obj_io.x_pos, cur_2d_obj_io.y_pos, cur_2d_obj_io.z_pos, cur_2d_obj_io.x_rot, cur_2d_obj_io.y_rot, cur_2d_obj_io.z_rot, 0); #endif // CLUSTER_INSIDES if (i % 250 == 0) { update_function(load_2d_object_str, progress); } #endif // FASTER_MAP_LOAD } LEAVE_DEBUG_MARK("load 2d objects"); #ifdef CLUSTER_INSIDES // If we need to compute the clusters, do it here, so that the // newly added lights and particle systems get the right cluster // number automagically. We don't update the occupation map with // lights or particle systems since I don't expect them to bridge // any clusters, and if they do happen to hang in the void, // they'll be shown anyway. if (!have_clusters) { compute_clusters (occupied); free (occupied); // Ok, we have the clusters, now assign new IDs to each // object that we added. for (i = 0; i < MAX_OBJ_3D; i++) { if (objects_list[i]) { int x = (int) (objects_list[i]->x_pos / 0.5f); int y = (int) (objects_list[i]->y_pos / 0.5f); objects_list[i]->cluster = get_cluster (x, y); } } for (i = 0; i < MAX_OBJ_2D; i++) { if (obj_2d_list[i]) { int x = (int) (obj_2d_list[i]->x_pos / 0.5f); int y = (int) (obj_2d_list[i]->y_pos / 0.5f); obj_2d_list[i]->cluster = get_cluster (x, y); } } } // we finally add the tiles to the abt for(i = 0; i < tile_map_size_y; i++) { bbox.bbmin[Y] = i*3.0f; bbox.bbmax[Y] = (i+1)*3.0f; if (i == 0) bbox.bbmin[Y] -= water_tiles_extension; else if (i == tile_map_size_y-1) bbox.bbmax[Y] += water_tiles_extension; for(j = 0; j < tile_map_size_x; j++) { current_cluster = get_cluster(j*6, i*6); cur_tile = tile_map[i*tile_map_size_x+j]; if (cur_tile != 255) { bbox.bbmin[X] = j*3.0f; bbox.bbmax[X] = (j+1)*3.0f; if (j == 0) bbox.bbmin[X] -= water_tiles_extension; else if (j == tile_map_size_x-1) bbox.bbmax[X] += water_tiles_extension; if (IS_WATER_TILE(cur_tile)) { bbox.bbmin[Z] = -0.25f; bbox.bbmax[Z] = -0.25f; if (IS_REFLECTING(cur_tile)) add_water_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile, 1); else add_water_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile, 0); } else { bbox.bbmin[Z] = 0.0f; bbox.bbmax[Z] = 0.0f; add_terrain_to_list(main_bbox_tree_items, get_terrain_id(j, i), bbox, cur_tile); } } } } #endif #ifdef FASTER_MAP_LOAD update_function(load_lights_str, 20.0f); #else // FASTER_MAP_LOAD progress = (cur_map_header.lights_no + 99) / 100; if (progress > 0) { update_function(load_lights_str, 0.0f); progress = 20.0f / progress; } else { update_function(load_lights_str, 20.0f); progress = 0.0f; } #endif // FASTER_MAP_LOAD LOG_DEBUG("Loading %d lights.", cur_map_header.lights_no); //read the lights lights = (light_io *) (file_mem + cur_map_header.lights_offset); ENTER_DEBUG_MARK("load lights"); for (i = 0; i < cur_map_header.lights_no; i++) { light_io cur_light_io = lights[i]; cur_light_io.pos_x = SwapLEFloat (cur_light_io.pos_x); cur_light_io.pos_y = SwapLEFloat (cur_light_io.pos_y); cur_light_io.pos_z = SwapLEFloat (cur_light_io.pos_z); cur_light_io.r = SwapLEFloat (cur_light_io.r); cur_light_io.g = SwapLEFloat (cur_light_io.g); cur_light_io.b = SwapLEFloat (cur_light_io.b); LOG_DEBUG("Adding light(%d) at <%d, %f, %f> with color " "<%f, %f, %f>.", i, cur_light_io.pos_x, cur_light_io.pos_y, cur_light_io.pos_z, cur_light_io.r, cur_light_io.g, cur_light_io.b); if (cur_light_io.pos_x < 0.0f || cur_light_io.pos_x > tile_map_size_x * 60 || cur_light_io.pos_y < 0.0f || cur_light_io.pos_y > tile_map_size_y * 60 || cur_light_io.pos_z < -1000.0f || cur_light_io.pos_z > 1000.0f || cur_light_io.r < -1.0f || cur_light_io.r > 1000.0f || cur_light_io.g < -1.0f || cur_light_io.g > 1000.0f || cur_light_io.b < -1.0f || cur_light_io.b > 1000.0f) { LOG_ERROR("Bad light (number %d) when loading '%s'; co-ords [%f %f %f] " "colour [%f %f %f]", i, file_name, cur_light_io.pos_x, cur_light_io.pos_y, cur_light_io.pos_z, cur_light_io.r, cur_light_io.g, cur_light_io.b); cur_light_io.pos_x = cur_light_io.pos_y = 1.0f; cur_light_io.pos_z = 2.0f; cur_light_io.r = cur_light_io.g = cur_light_io.b = 1.0f; continue; } add_light (cur_light_io.pos_x, cur_light_io.pos_y, cur_light_io.pos_z, cur_light_io.r, cur_light_io.g, cur_light_io.b, 1.0f, 0); #ifndef FASTER_MAP_LOAD if (i % 100 == 0) { update_function(load_lights_str, progress); } #endif } LEAVE_DEBUG_MARK("load lights"); #ifdef FASTER_MAP_LOAD update_function(load_particles_str, 20.0f); #else // FASTER_MAP_LOAD progress = (cur_map_header.particles_no + 99) / 100; if (progress > 0.0f) { update_function(load_particles_str, 0.0f); progress = 20.0f / progress; } else { update_function(load_particles_str, 20.0f); progress = 0.0f; } #endif // FASTER_MAP_LOAD LOG_DEBUG("Loading %d particles.", cur_map_header.particles_no); //read particle systems particles = (particles_io *) (file_mem + cur_map_header.particles_offset); ENTER_DEBUG_MARK("load particles"); for (i = 0; i < cur_map_header.particles_no; i++) { particles_io cur_particles_io = particles[i]; cur_particles_io.x_pos = SwapLEFloat (cur_particles_io.x_pos); cur_particles_io.y_pos = SwapLEFloat (cur_particles_io.y_pos); cur_particles_io.z_pos = SwapLEFloat (cur_particles_io.z_pos); LOG_DEBUG("Adding particle(%d) '%s' at <%d, %f, %f>.", i, cur_particles_io.file_name, cur_particles_io.x_pos, cur_particles_io.y_pos, cur_particles_io.z_pos); if (!strncmp(cur_particles_io.file_name, "ec://", 5)) { ec_create_effect_from_map_code(cur_particles_io.file_name + 5, cur_particles_io.x_pos, cur_particles_io.y_pos, cur_particles_io.z_pos, (poor_man ? 6 : 10)); } else { #ifdef NEW_SOUND add_map_particle_sys (cur_particles_io.file_name, cur_particles_io.x_pos, cur_particles_io.y_pos, cur_particles_io.z_pos, 0); #else add_particle_sys (cur_particles_io.file_name, cur_particles_io.x_pos, cur_particles_io.y_pos, cur_particles_io.z_pos, 0); #endif // NEW_SOUND } #ifndef FASTER_MAP_LOAD if (i % 100 == 0) { update_function(load_particles_str, progress); } #endif } LEAVE_DEBUG_MARK("load particles"); // Everything copied, get rid of the file data el_close(file); update_function(bld_sectors_str, 0.0f); LOG_DEBUG("Building bbox tree for map '%s'.", file_name); init_bbox_tree(main_bbox_tree, main_bbox_tree_items); free_bbox_items(main_bbox_tree_items); main_bbox_tree_items = 0; update_function(init_done_str, 20.0f); #ifdef EXTRA_DEBUG ERR();//We finished loading the new map apparently... #endif return 1; }