static void cleanup()
{
	if (!initialized)
		return;

	if (prev_win)
		unuse_pack(&prev_win);
	if (pack_data) {
		struct pack_window *win, *prev;
		for (prev = NULL, win = pack_data->windows;
		     win; prev = win, win = win->next) {
			if (win != pack_win)
				continue;
			if (prev)
				prev->next = win->next;
			else
				pack_data->windows = win->next;
			break;
		}
	}
	if (pack_win) {
		free(pack_win->base);
		free(pack_win);
	}

	end_packfile();

	if (!require_explicit_termination)
		dump_branches();

	unkeep_all_packs();

	initialized = 0;

	pack_report();
}
int
add_pack(struct linked_list *item, int print_message)
{
    struct object   *obj, *op;
    int from_floor;

    if (item == NULL)
    {
        from_floor = TRUE;

        if ((item = find_obj(hero.y, hero.x)) == NULL)
        {
            msg("Nothing to pick up.");
            return(FALSE);
        }
    }
    else
        from_floor = FALSE;

    if (from_floor)
    {
        item = get_stack(item);

        if (!item)
            return(FALSE);
    }

    obj = OBJPTR(item);

    /* If it is gold, just add its value to rogue's purse and get rid of */

    if (obj->o_type == GOLD)
    {
        struct linked_list  *mitem;
        struct thing    *tp;

        if (print_message)
        {
            if (!terse)
                addmsg("You found ");

            msg("%d gold pieces.", obj->o_count);
        }

        /*
         * First make sure no greedy monster is after this gold. If
         * so, make the monster run after the rogue instead.
         */

        for (mitem = mlist; mitem != NULL; mitem = next(mitem))
        {
            tp = THINGPTR(mitem);

            if (tp->t_horde==obj)
            {
                tp->t_ischasing = TRUE;
                tp->t_chasee = &player;
                tp->t_horde  = NULL;
            }
        }

        /*
         * This will cause problems if people are able to drop and
         * pick up gold, or when GOLDSTEAL monsters are killed.
         */

        /* Thieves get EXP for gold they pick up */

        if (player.t_ctype == C_THIEF)
        {
            pstats.s_exp += obj->o_count / 4;
            check_level();
        }

        purse += obj->o_count;

        if (from_floor)
            rem_obj(item, TRUE);    /* Remove object from the level */

        return (TRUE);
    }

    /* see if he can carry any more weight */

    if (itemweight(obj) + pstats.s_pack > pstats.s_carry)
    {
        msg("Too much for you to carry.");

        if (print_message)
        {
            msg("%s onto %s", terse ? "Moved" : "You moved",
                inv_name(obj, LOWERCASE));
        }

        return(FALSE);
    }

    /*
     * Link it into the pack. If the item can be grouped, try to find its
     * neighbors and bump the count. A special case is food, which can't
     * be grouped, but an exact match allows the count to get
     * incremented.
     */

    if ((op = apply_to_bag(pack, obj->o_type, bff_group, NULL, obj)) != NULL)
    {
        op->o_count += obj->o_count;    /* add it to the rest */

        if (from_floor)
            rem_obj(item, FALSE);

        pack_report(op, print_message, "You now have ");

        return(TRUE);
    }

    /* Check for and deal with scare monster scrolls */

    if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
        if (obj->o_flags & ISCURSED)
        {
            msg("The scroll turns to dust as you pick it up.");
            rem_obj(item, TRUE);
            return(TRUE);
        }

    /* Check if there is room */

    if (count_bag(pack, obj->o_type, NULL) == max_print())
    {
        msg("You have no room for more %s.", name_type(obj->o_type));

        if (print_message)
        {
            obj = OBJPTR(item);
            msg("%s onto %s.", terse ? "Moved" : "You moved",
                inv_name(obj, LOWERCASE));
        }

        return(FALSE);
    }

    /*
     * finally, add the new item to the bag, and free up the linked list
     * on top of it.
     */

    if (from_floor)
        rem_obj(item, FALSE);

    push_bag(&pack, obj);
    pack_report(obj, print_message, "You now have ");
    ur_free(item);

    return(TRUE);      /* signal success */
}