Esempio n. 1
0
/*! \brief Tests a if a given OBJECT was hit at a given set of coordinates
 *
 *  \par Function Description
 *  Tests a if a given OBJECT was hit at a given set of coordinates. If an
 *  object is not selectable (e.g. it is locked), or it is invisible and
 *  not being rendered, this function will return FALSE.
 *
 *  \param [in] w_current         The GschemToplevel object.
 *  \param [in] object            The OBJECT being hit-tested.
 *  \param [in] w_x               The X coordinate to test (in world coords).
 *  \param [in] w_y               The Y coordinate to test (in world coords).
 *  \param [in] w_slack           The slack applied to the hit-test.
 *
 *  \returns TRUE if the OBJECT was hit, otherwise FALSE.
 */
static gboolean
is_object_hit (GschemToplevel *w_current, OBJECT *object,
               int w_x, int w_y, int w_slack)
{
  int left, top, right, bottom;

  if (!object->selectable)
    return FALSE;

  /* We can't hit invisible (text) objects unless show_hidden_text is active.
   */
  if (!o_is_visible (object) && !w_current->toplevel->show_hidden_text)
    return FALSE;

  /* Do a coarse test first to avoid computing distances for objects ouside
   * of the hit range.
   */
  if (!world_get_single_object_bounds(w_current->toplevel, object,
                                      &left, &top, &right, &bottom) ||
      !inside_region (left  - w_slack, top    - w_slack,
                      right + w_slack, bottom + w_slack,
                      w_x, w_y))
    return FALSE;

  return (o_shortest_distance (w_current->toplevel, object, w_x, w_y) < w_slack);
}
Esempio n. 2
0
static errval_t do_single_modify_flags(struct pmap_arm *pmap, genvaddr_t vaddr,
                                       size_t pages, vregion_flags_t flags)
{
    errval_t err = SYS_ERR_OK;
    struct vnode *ptable = find_ptable(pmap, vaddr);
    uint16_t ptentry = ARM_USER_L2_OFFSET(vaddr);
    if (ptable) {
        struct vnode *page = find_vnode(ptable, ptentry);
        if (page) {
            if (inside_region(ptable, ptentry, pages)) {
                // we're modifying part of a valid mapped region
                // arguments to invocation: invoke frame cap, first affected
                // page (as offset from first page in mapping), #affected
                // pages, new flags. Invocation should check compatibility of
                // new set of flags with cap permissions.
                size_t off = ptentry - page->entry;
                uintptr_t pmap_flags = vregion_flags_to_kpi_paging_flags(flags);
                err = invoke_frame_modify_flags(page->u.frame.cap, off, pages, pmap_flags);
                printf("invoke_frame_modify_flags returned error: %s (%"PRIuERRV")\n",
                        err_getstring(err), err);
                return err;
            } else {
                // overlaps some region border
                return LIB_ERR_PMAP_EXISTING_MAPPING;
            }
        }
    }
    return SYS_ERR_OK;
}
Esempio n. 3
0
/*
 * check whether player enters/leaves one or more regions.
 */
boolean
in_out_region(struct level *lev, xchar x, xchar y)
{
    int i, f_indx;

    /* First check if we can do the move */
    for (i = 0; i < lev->n_regions; i++) {
        if (inside_region(lev->regions[i], x, y)
            && !hero_inside(lev->regions[i]) && !lev->regions[i]->attach_2_u) {
            if ((f_indx = lev->regions[i]->can_enter_f) != NO_CALLBACK)
                if (!(*callbacks[f_indx]) (lev->regions[i], 0))
                    return FALSE;
        } else if (hero_inside(lev->regions[i])
                   && !inside_region(lev->regions[i], x, y)
                   && !lev->regions[i]->attach_2_u) {
            if ((f_indx = lev->regions[i]->can_leave_f) != NO_CALLBACK)
                if (!(*callbacks[f_indx]) (lev->regions[i], 0))
                    return FALSE;
        }
    }

    /* Callbacks for the regions we do leave */
    for (i = 0; i < lev->n_regions; i++)
        if (hero_inside(lev->regions[i]) && !lev->regions[i]->attach_2_u &&
            !inside_region(lev->regions[i], x, y)) {
            clear_hero_inside(lev->regions[i]);
            if (lev->regions[i]->leave_msg != NULL)
                pline("%s", lev->regions[i]->leave_msg);
            if ((f_indx = lev->regions[i]->leave_f) != NO_CALLBACK)
                (void)(*callbacks[f_indx]) (lev->regions[i], 0);
        }

    /* Callbacks for the regions we do enter */
    for (i = 0; i < lev->n_regions; i++)
        if (!hero_inside(lev->regions[i]) && !lev->regions[i]->attach_2_u &&
            inside_region(lev->regions[i], x, y)) {
            set_hero_inside(lev->regions[i]);
            if (lev->regions[i]->enter_msg != NULL)
                pline("%s", lev->regions[i]->enter_msg);
            if ((f_indx = lev->regions[i]->enter_f) != NO_CALLBACK)
                (void)(*callbacks[f_indx]) (lev->regions[i], 0);
        }
    return TRUE;
}
Esempio n. 4
0
/*
 * check whether a monster enters/leaves one or more region.
*/
boolean
m_in_out_region(struct monst * mon, xchar x, xchar y)
{
    int i, f_indx;

    /* First check if we can do the move */
    for (i = 0; i < mon->dlevel->n_regions; i++) {
        if (inside_region(mon->dlevel->regions[i], x, y) &&
            !mon_in_region(mon->dlevel->regions[i], mon) &&
            mon->dlevel->regions[i]->attach_2_m != mon->m_id) {
            if ((f_indx = mon->dlevel->regions[i]->can_enter_f) != NO_CALLBACK)
                if (!(*callbacks[f_indx]) (mon->dlevel->regions[i], mon))
                    return FALSE;
        } else if (mon_in_region(mon->dlevel->regions[i], mon) &&
                   !inside_region(mon->dlevel->regions[i], x, y) &&
                   mon->dlevel->regions[i]->attach_2_m != mon->m_id) {
            if ((f_indx = mon->dlevel->regions[i]->can_leave_f) != NO_CALLBACK)
                if (!(*callbacks[f_indx]) (mon->dlevel->regions[i], mon))
                    return FALSE;
        }
    }

    /* Callbacks for the regions we do leave */
    for (i = 0; i < mon->dlevel->n_regions; i++)
        if (mon_in_region(mon->dlevel->regions[i], mon) &&
            mon->dlevel->regions[i]->attach_2_m != mon->m_id &&
            !inside_region(mon->dlevel->regions[i], x, y)) {
            remove_mon_from_reg(mon->dlevel->regions[i], mon);
            if ((f_indx = mon->dlevel->regions[i]->leave_f) != NO_CALLBACK)
                (void)(*callbacks[f_indx]) (mon->dlevel->regions[i], mon);
        }

    /* Callbacks for the regions we do enter */
    for (i = 0; i < mon->dlevel->n_regions; i++)
        if (!hero_inside(mon->dlevel->regions[i]) &&
            !mon->dlevel->regions[i]->attach_2_u &&
            inside_region(mon->dlevel->regions[i], x, y)) {
            add_mon_to_reg(mon->dlevel->regions[i], mon);
            if ((f_indx = mon->dlevel->regions[i]->enter_f) != NO_CALLBACK)
                (void)(*callbacks[f_indx]) (mon->dlevel->regions[i], mon);
        }
    return TRUE;
}
Esempio n. 5
0
/*
 * Check if a spot is under a visible region (eg: gas cloud).
 * Returns NULL if not, otherwise returns region.
 */
struct region *
visible_region_at(struct level *lev, xchar x, xchar y)
{
    int i;

    for (i = 0; i < lev->n_regions; i++)
        if (inside_region(lev->regions[i], x, y) && lev->regions[i]->visible &&
            lev->regions[i]->ttl != 0)
            return lev->regions[i];
    return NULL;
}
Esempio n. 6
0
/*
 * Checks player's regions after a teleport for instance.
 */
void
update_player_regions(struct level *lev)
{
    int i;

    for (i = 0; i < lev->n_regions; i++)
        if (!lev->regions[i]->attach_2_u &&
            inside_region(lev->regions[i], u.ux, u.uy))
            set_hero_inside(lev->regions[i]);
        else
            clear_hero_inside(lev->regions[i]);
}
Esempio n. 7
0
/*
 * Add a region to the list.
 * This actually activates the region.
 */
void
add_region(struct level *lev, struct region *reg)
{
    struct region **tmp_reg;
    int i, j;

    if (lev->max_regions <= lev->n_regions) {
        tmp_reg = lev->regions;
        lev->regions =
            malloc(sizeof (struct region *) * (lev->max_regions + 10));
        if (lev->max_regions > 0) {
            memcpy(lev->regions, tmp_reg,
                   lev->max_regions * sizeof (struct region *));
            free(tmp_reg);
        }
        lev->max_regions += 10;
    }
    reg->lev = lev;
    lev->regions[lev->n_regions] = reg;
    lev->n_regions++;
    /* Check for monsters inside the region */
    for (i = reg->bounding_box.lx; i <= reg->bounding_box.hx; i++)
        for (j = reg->bounding_box.ly; j <= reg->bounding_box.hy; j++) {
            /* Some lev->regions can cross the level boundaries */
            if (!isok(i, j))
                continue;
            if (MON_AT(level, i, j) && inside_region(reg, i, j))
                add_mon_to_reg(reg, level->monsters[i][j]);
            if (reg->visible && cansee(i, j))
                newsym(i, j);
        }
    /* Check for player now... */
    if (inside_region(reg, u.ux, u.uy))
        set_hero_inside(reg);
    else
        clear_hero_inside(reg);
}
Esempio n. 8
0
/*
 * Ditto for a specified monster.
 */
void
update_monster_region(struct monst *mon)
{
    int i;

    for (i = 0; i < mon->dlevel->n_regions; i++) {
        if (inside_region(mon->dlevel->regions[i], mon->mx, mon->my)) {
            if (!mon_in_region(mon->dlevel->regions[i], mon))
                add_mon_to_reg(mon->dlevel->regions[i], mon);
        } else {
            if (mon_in_region(mon->dlevel->regions[i], mon))
                remove_mon_from_reg(mon->dlevel->regions[i], mon);
        }
    }
}
Esempio n. 9
0
/*
 * Remove a region from the list & free it.
 */
void
remove_region(struct region *reg)
{
    int i, x, y;
    struct level *lev = reg->lev;

    for (i = 0; i < reg->lev->n_regions; i++)
        if (reg->lev->regions[i] == reg)
            break;
    if (i == reg->lev->n_regions)
        return;

    /* Update screen if necessary */
    if (reg->visible && level == lev)
        for (x = reg->bounding_box.lx; x <= reg->bounding_box.hx; x++)
            for (y = reg->bounding_box.ly; y <= reg->bounding_box.hy; y++)
                if (isok(x, y) && inside_region(reg, x, y) && cansee(x, y))
                    newsym(x, y);

    free_region(reg);
    lev->regions[i] = lev->regions[lev->n_regions - 1];
    lev->regions[lev->n_regions - 1] = NULL;
    lev->n_regions--;
}