예제 #1
0
파일: mines.c 프로젝트: csiga/Eternal-Lands
void add_mines_from_list (const Uint8 *data)
{
	Uint16 mines_no;
	int i;
	int mine_x, mine_y, mine_type, my_offset;
	float x, y, z;
	int obj_3d_id, mine_id;

	mines_no = data[0];

	if (mines_no > NUM_MINES)
	{
		return;		// Something nasty happened
	}
	
	for (i = 0; i < mines_no; i++)
	{
		my_offset = i * 6 + 1;
		mine_x = SDL_SwapLE16(*((Uint16 *)(data + my_offset)));
		mine_y = SDL_SwapLE16(*((Uint16 *)(data + my_offset + 2)));
		mine_id = *((Uint8 *)(data + my_offset + 4));
		mine_type = *((Uint8 *)(data + my_offset + 5));
		if (mine_id >= NUM_MINES)
		{
			continue;
		}
		// Now, get the Z position
		if (mine_y * tile_map_size_x * 6 + mine_x > tile_map_size_x * tile_map_size_y * 6 * 6)
		{
			// Warn about this error!
			LOG_ERROR("A mine was located OUTSIDE the map!\n");
			continue;
		}
		
		z = -2.2f + height_map[mine_y * tile_map_size_x * 6 + mine_x] * 0.2f;
		// Convert from height values to meters
		x = (float)mine_x / 2;
		y = (float)mine_y / 2;
		// Center the object
		x = x + 0.25f;
		y = y + 0.25f;
	
		// Now, find the place into the mines list, so we can destroy the mine properly
		if (mine_list[mine_id].obj_3d_id != -1)
		{
			char buf[256];

			// Oops, slot already taken!
			safe_snprintf(buf, sizeof(buf), "Oops, trying to add an existing mine! id=%d\n", mine_id);
			LOG_ERROR(buf);
			return;
		}

		obj_3d_id = add_e3d(get_mine_e3d(mine_type), x, y, z, 0, 0, 0, 1, 0, 1.0f, 1.0f, 1.0f, 1);
		mine_list[mine_id].x = mine_x;
		mine_list[mine_id].y = mine_y;
		mine_list[mine_id].type = mine_type;
		mine_list[mine_id].obj_3d_id = obj_3d_id;
	}
}
예제 #2
0
void open_3d_obj()
{
  OPENFILENAME ofn;
  char szFileName[MAX_PATH], temp[MAX_PATH];

  ZeroMemory (&ofn, sizeof (ofn));
  szFileName[0] = 0;

  ofn.lStructSize = sizeof (ofn);
  ofn.hwndOwner = 0;
  ofn.lpstrFilter = "Custom e3d (*.e3d)\0*.e3d\0Compressed e3d (*.e3d.gz)\0*.e3d.gz\0\0";
  ofn.lpstrFile = szFileName;
  ofn.nMaxFile = MAX_PATH;
  ofn.lpstrDefExt = "e3d";
  strcpy(temp,exec_path);
  strcat(temp,"\\3dobjects\\");
  ofn.lpstrInitialDir = temp;

    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
    if (GetOpenFileName (&ofn))
    {
		char proper_path[128];
		get_proper_path (szFileName, exec_path, proper_path, sizeof (proper_path) );
		if(!strcmp(proper_path+strlen(proper_path)-3, ".gz")) proper_path[strlen(proper_path)-3]= '\0';
		selected_3d_object=add_e3d(proper_path,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
		cur_tool=tool_select;//change the current tool
    }

}
예제 #3
0
void open_3d_obj_continued()
{
  if (selected_file)
  {
		char *file = selected_file;
		size_t datadir_len = strlen(datadir);

		if(!strcmp(selected_file+strlen(selected_file)-3, ".gz")) {
			selected_file[strlen(selected_file)-3]= '\0';
		}
		if(datadir_len > 0 && strncmp(selected_file, datadir, datadir_len) == 0) {
			/* add_e3d() wants a path relative to the data dir */
			if (file[datadir_len-1] == '/')
				file += datadir_len-2;
			else
				file += datadir_len-1;
			*file = '.';
		}
		selected_3d_object=add_e3d(file,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
		cur_tool=tool_select;//change the current tool
		if(selected_particles_object>=0) {
			// we dont want the particle sys to disapear
			particles_list[selected_particles_object]->ttl=-1;
		}
#ifdef GTK2
		cur_mode=mode_3d;
#endif
  }
}
예제 #4
0
void get_3d_objects(char *d)
{
	int i;
	Uint16 global_id;
	Uint8 local_id;
	Uint16 object_type;
	Uint16 object_size=0;

	Uint8 numobjects=*(Uint8*)d;

	d++;
	for(i=0;i<numobjects;i++){
		int k;
		object3d_io o3dio;

		memset(&o3dio,0,sizeof(object3d_io));

		o3dio.object_type=*(Uint16*)d;
		d+=2;
		o3dio.x_pos=*(Uint16*)d;
		d+=2;
		o3dio.y_pos=*(Uint16*)d;
		d+=2;
		o3dio.z_pos=*(Uint8*)d;
		d++;
		o3dio.z_rot=*(Uint8*)d;
		d++;
		global_id=*(Uint16 *)d;
		d+=2;
		local_id=*(Uint8 *)d;
		d++;

		object_size=0;
		object_type=o3dio.object_type;
		if(object_type>8191)
		{
			object_size=object_type>>13;
			object_type=object_type&0x1fff;
		}

		k=add_e3d(e3dlist_getname(object_type),sector_to_global_x(active_sector,o3dio.x_pos), sector_to_global_y(active_sector,o3dio.y_pos) ,
		sector_to_global_z(o3dio.z_pos),o3dio.x_rot*1.5,o3dio.y_rot*1.5,o3dio.z_rot*1.5,
		o3dio.flags&0x1,o3dio.flags&0x2,o3dio.r/255.0f,o3dio.g/255.0f,o3dio.b/255.0f, o3dio.attributes);

		// put the object in global id
		if(global_id!=k)
			{
				objects_list[global_id]=objects_list[k];
				objects_list[k]=0;
			}

		memcpy(&objects_list[global_id]->o3dio,&o3dio,sizeof(object3d_io));
		objects_list[global_id]->object_size=object_size;

		sector_add_3do(global_id,local_id);
	}
예제 #5
0
void clone_3d_object(int object_id)
{
	float z_pos,x_rot,y_rot,z_rot,r,g,b;
	char self_lit,blended;

	z_pos=objects_list[object_id]->z_pos;
	x_rot=objects_list[object_id]->x_rot;
	y_rot=objects_list[object_id]->y_rot;
	z_rot=objects_list[object_id]->z_rot;
	self_lit=objects_list[object_id]->self_lit;
	blended=objects_list[object_id]->blended;
	r=objects_list[object_id]->color[0];
	g=objects_list[object_id]->color[1];
	b=objects_list[object_id]->color[2];

	z_pos=(z_pos == 0.01f)?0.02f:(z_pos == 0.02f?0.01f:z_pos);

	selected_3d_object=add_e3d(objects_list[object_id]->file_name,scene_mouse_x,scene_mouse_y,z_pos,x_rot,y_rot,z_rot,self_lit,blended,r,g,b);
	cur_tool=tool_select;//change the current tool
}
예제 #6
0
파일: mines.c 프로젝트: csiga/Eternal-Lands
void put_mine_on_ground(int mine_x, int mine_y, int mine_type, int mine_id)
{
	float x, y, z;
	int obj_3d_id;
	
	// Now, get the Z position
	if (mine_y * tile_map_size_x * 6 + mine_x > tile_map_size_x * tile_map_size_y * 6 * 6)
	{
		//Warn about this error:
		LOG_ERROR("A mine was placed OUTSIDE the map!\n");
		return;
	}
	
	z = -2.2f + height_map[mine_y * tile_map_size_x * 6 + mine_x] * 0.2f;
	// Convert from height values to meters
	x = (float)mine_x / 2;
	y = (float)mine_y / 2;
	// Center the object
	x = x + 0.25f;
	y = y + 0.25f;

	// Now, find a place into the mines list, so we can destroy the mine properly
	if (mine_list[mine_id].obj_3d_id != -1)
	{
		char buf[256];

		// Oops, slot already taken!
		safe_snprintf(buf, sizeof(buf), "Oops, trying to add an existing mine! id=%d\n", mine_id);
		LOG_ERROR(buf);
		return;
	}
	
	obj_3d_id = add_e3d(get_mine_e3d(mine_type), x, y, z, 0, 0, 0, 1, 0, 1.0f, 1.0f, 1.0f, 1);
	mine_list[mine_id].x = mine_x;
	mine_list[mine_id].y = mine_y;
	mine_list[mine_id].type = mine_type;
	mine_list[mine_id].obj_3d_id = obj_3d_id;
}
예제 #7
0
int check_browser_interface (window_info *win, int _x, int _y)
{
   	if (view_browser && _x > win->len_x-20 && _y <= 20)
	{
		view_browser = 0;
		return 1;
	}

	if(cd==-1){
		int id = _y / 18;
		if (_x > 210) id += 22;

		if(mc==1){
			if(id<=cc){
				ccat=id;
				mc=0;
				if(Cat[ccat].ns==1){
					int i=0;
					for(;i<dc;i++){
						if(Cat[ccat].Sub[0]==&Dir[i])
							cd=i;
					}
					mc=1;
				}
				
			}
		}else{
			if(id<Cat[ccat].ns){
				int i=0;
				for(;i<dc;i++){
					if(Cat[ccat].Sub[id]==&Dir[i])
						cd=i;
				}
			} else if(_x > win->len_x-16 && _y > 160 && _y < 240){
				mc=1;
			}
		}

	}else{
		if(_x>0 && _x<200 && _y>0 && _y<200){
			char fn[256];
			strcpy(fn,".");
			strcat(fn,Dir[cd].Files[cp]);
			selected_3d_object=add_e3d(fn,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
			cur_tool=tool_select;
			if(close_browser_on_select) toggle_window(browser_win);
		}
		if(cp+2<Dir[cd].nf && _x>0 && _x<200 && _y>200 && _y<400){
			char fn[256];
			strcpy(fn,".");
			strcat(fn,Dir[cd].Files[cp+2]);
			selected_3d_object=add_e3d(fn,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
			cur_tool=tool_select;
			if(close_browser_on_select) toggle_window(browser_win);
		}
		if(cp+1<Dir[cd].nf && _x>200 && _x<400 && _y>0 && _y<200){
			char fn[256];
			strcpy(fn,".");
			strcat(fn,Dir[cd].Files[cp+1]);
			selected_3d_object=add_e3d(fn,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
			cur_tool=tool_select;
			if(close_browser_on_select) toggle_window(browser_win);
		}
		if(cp+3<Dir[cd].nf && _x>200 && _x<400 && _y>200 && _y<400){
			char fn[256];
			strcpy(fn,".");
			strcat(fn,Dir[cd].Files[cp+3]);
			selected_3d_object=add_e3d(fn,scene_mouse_x,scene_mouse_y,0,0,0,0,0,0,0,0,0);
			cur_tool=tool_select;
			if(close_browser_on_select) toggle_window(browser_win);
		}
	

		if(_x > win->len_x-16 && _x < win->len_x && _y > 18 && _y < 18+16){
			if(cp>=4)cp-=4;	
		}

		if(_x > win->len_x-16 && _x < win->len_x && _y > 380 && _y < 380+16){
			if(cp<(Dir[cd].nf-4))cp+=4;
		}

		if(_x > win->len_x-16 && _x < win->len_x && _y > 160 && _y < 240){
			cp=0;
			cd=-1;
		}
   }
   return 1;
}
예제 #8
0
void add_bags_from_list (const Uint8 *data)
{
	Uint16 bags_no;
	int i;
	int bag_x,bag_y,my_offset; //bag_type unused?
	float x,y,z;
	int obj_3d_id, bag_id;

	bags_no=data[0];

	if(bags_no > NUM_BAGS) {
		return;//something nasty happened
	}

	for(i=0;i<bags_no;i++) {
		my_offset=i*5+1;
		bag_x=SDL_SwapLE16(*((Uint16 *)(data+my_offset)));
		bag_y=SDL_SwapLE16(*((Uint16 *)(data+my_offset+2)));
		bag_id=*((Uint8 *)(data+my_offset+4));
		if(bag_id >= NUM_BAGS) {
			continue;
		}
		//now, get the Z position
		if (!get_tile_valid(bag_x, bag_y))
		{
			//Warn about this error!
			LOG_WARNING("A bag was located OUTSIDE the map!\n");
			continue;
		}

		z = get_tile_height(bag_x, bag_y);
		//convert from height values to meters
		x=(float)bag_x/2;
		y=(float)bag_y/2;
		//center the object (slightly randomized)
		x = x + 0.25f; // + get_bag_offset_x(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y);
		y = y + 0.25f; // + get_bag_offset_y(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y);

		// DEBUG
		LOG_DEBUG_VERBOSE("bag <%i> (%f,%f) rot %f tilt %f\n", bag_id, x, y,
			get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y),
			get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y));

		if (use_eye_candy) {
	#ifdef ONGOING_BAG_EFFECT
			// start an ongoing effect until the ongoing bag effect is coded
			bag_list[bag_id].ongoing_bag_effect_reference = ec_create_lamp(x, y, z, 0.0, 1.0, 0.75, (poor_man ? 6 : 10));
	#endif // ONGOING_BAG_EFFECT
		}

		// Now, find a place into the bags list, so we can destroy the bag properly
		if (bag_list[bag_id].obj_3d_id != -1) {
			char buf[256];
			// oops, slot already taken!
			safe_snprintf(buf, sizeof(buf), "Oops, trying to add an existing bag! id=%d\n", bag_id);
			LOG_ERROR(buf);
			return;
		}

#ifdef OLD_MISC_OBJ_DIR
		obj_3d_id = add_e3d("./3dobjects/misc_objects/bag1.e3d", x, y, z,
#else
		obj_3d_id = add_e3d("./3dobjects/bag1.e3d", x, y, z,
#endif
			get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 0,
			get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y),
			1, 0, 1.0f, 1.0f, 1.0f, 1);
		bag_list[bag_id].x=bag_x;
		bag_list[bag_id].y=bag_y;
		bag_list[bag_id].obj_3d_id=obj_3d_id;
	}
}
예제 #9
0
void put_bag_on_ground(int bag_x,int bag_y,int bag_id)
{
	float x,y,z;
	int obj_3d_id;
#ifdef NEW_SOUND
	int snd;
#endif // NEW_SOUND

	//now, get the Z position
	if (!get_tile_valid(bag_x, bag_y))
	{
		//Warn about this error:
		LOG_WARNING("A bag was placed OUTSIDE the map!\n");
		return;
	}

	z = get_tile_height(bag_x, bag_y);
	//convert from height values to meters
	x=(float)bag_x/2;
	y=(float)bag_y/2;
	//center the object (slightly randomized)
	x = x + 0.25f; // + get_bag_offset_x(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y);
	y = y + 0.25f; // + get_bag_offset_y(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y);

	// DEBUG
	// printf("bag <%i> (%f,%f) rot %f tilt %f\n", bag_id, x, y,
	//	get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y),
	//	get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y));

	//Launch the animation
	if (use_eye_candy) {
		ec_create_bag_drop(x, y, z, (poor_man ? 6 : 10));
#ifdef ONGOING_BAG_EFFECT
		// start an ongoing effect until the ongoing bag effect is coded
		bag_list[bag_id].ongoing_bag_effect_reference = ec_create_lamp(x, y, z, 0.0, 1.0, 0.75, (poor_man ? 6 : 10));
#endif // ONGOING_BAG_EFFECT
	}
#ifdef NEW_SOUND
	if (your_actor && bag_x == your_actor->x_pos * 2 && bag_y == your_actor->y_pos * 2)
	{
		snd = get_sound_index_for_particle_file_name("./particles/bag_in.part");
		if (snd >= 0)
		{
			add_sound_object (snd, bag_x, bag_y, 0);
		}
	}
#endif // NEW_SOUND

#ifdef OLD_MISC_OBJ_DIR
	obj_3d_id=add_e3d("./3dobjects/misc_objects/bag1.e3d", x, y, z,
#else
	obj_3d_id=add_e3d("./3dobjects/bag1.e3d", x, y, z,
#endif
		get_bag_tilt(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y), 0,
		get_bag_rotation(bag_x, bag_y, bag_id, tile_map_size_x, tile_map_size_y),
		1 ,0 ,1.0f ,1.0f, 1.0f, 1);

	//now, find a place into the bags list, so we can destroy the bag properly
	bag_list[bag_id].x=bag_x;
	bag_list[bag_id].y=bag_y;
	bag_list[bag_id].obj_3d_id=obj_3d_id;
}
예제 #10
0
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;
}