/** * Put item in place like hand, belt, backpack etc. * @return 1 if successful */ int Place::put(Item *it, int xx, int yy) { ASSERT(it->m_place == NULL); //If an item is dropped, make it fall down if (m_cell != NULL) { Position p = m_cell->get_position(); if ((p.level() > 0) && (map->mcd(p.level(), p.column(), p.row(), 0)->No_Floor) && !(map->isStairs(p.level()-1, p.column(), p.row()))) return map->place(p.level()-1, p.column(), p.row())->put(it, xx, yy); } if (isfree(xx, yy) && isfit(it, xx, yy)) { if (m_item != NULL) m_item->m_prev = it; it->m_next = m_item; it->m_prev = NULL; it->m_place = this; it->setpos(xx, yy); m_item = it; /* if this place belongs to a map cell */ if (m_cell != NULL) { Position p = m_cell->get_position(); map->update_seen_item(p); if (it->obdata_ownLight()) /* if item has own light - an electro flare */ map->add_light_source(p.level(), p.column(), p.row(), it->obdata_ownLight()); } return 1; } return 0; }
/* * Attempt to acquire the lease. * Return 1 if succedded, 0 if not , and < 0 on errors. */ int acquire(int fd, off_t offset, char *id, int busyloop, long long *ts) { char curr[taglen+1] = "", last[taglen+1] = "", tag[taglen+1] = ""; long backoff_usec = (lease_ms + 6 * op_max_ms) * 1000; long contend_usec = (2 * op_max_ms) * 1000; char dummyid[idlen+1]; if (readtag(fd, offset, curr, 1) < 0) return -errno; settag(last, freetag); do { DEBUG("restart: curr tag is '%s'", curr); if (!sametag(curr, last) && !isfree(curr)) do { DEBUG("backoff: curr tag is '%s'", curr); settag(last, curr); usleep(backoff_usec); if (readtag(fd, offset, curr, 1) < 0) return -errno; } while (busyloop && !sametag(curr, last) && !isfree(curr)); if (!sametag(curr, last) && !isfree(curr)) { DEBUG("fail: curr tag is '%s'", curr); return 0; } DEBUG("contend: curr tag is '%s'", curr); if (writetimestamp(fd, offset, id, tag, ts) < 0) { DEBUG("lost (writetimestamp failed) : curr tag is %s", curr); return -errno; } usleep(contend_usec); if (readtag(fd, offset, curr, 1) < 0) { DEBUG("lost (readtag failed) : curr tag is %s", curr); return -errno; } } while (busyloop && !sametag(curr, tag)); if (busyloop || sametag(curr, tag)) { DEBUG("won : curr tag is %s", curr); querytag(curr, dummyid, ts); return renew(fd, offset, id, ts); } DEBUG("lost : curr tag is %s\n our tag is %s", curr, tag); return 0; }
/** * Test if item fits into a place like hand, belt, backpack etc. * Return 1 if it fits, 0 otherwise */ int Place::isfit(Item * it, int xx, int yy) { if (ishand() && (m_item != NULL)) return 0; for (int i = xx; i < xx + it->obdata_width(); i++) for (int j = yy; j < yy + it->obdata_height(); j++) if (!isfree(i, j)) return 0; return 1; }
int canmove(void) { Click c; for(c.d = Depth - 1; c.d >= 0; c.d--) for(c.y = 0; c.y < Ly; c.y++) for(c.x = 0; c.x < Lx; c.x++) if(level.board[c.d][c.x][c.y].which == TL && isfree(c) && bmatch(c) != nil) return 1; return 0; }
static void donames(int fd, struct fs *super, char *name) { int c; ino_t inode, inode1; ino_t maxino; union dinode *dp; maxino = super->fs_ncg * super->fs_ipg - 1; /* first skip the name of the filesystem */ while ((c = getchar()) != EOF && (c < '0' || c > '9')) while ((c = getchar()) != EOF && c != '\n'); ungetc(c, stdin); inode1 = -1; while (scanf("%d", &inode) == 1) { if (inode < 0 || inode > maxino) { #ifndef COMPAT fprintf(stderr, "invalid inode %llu\n", (unsigned long long)inode); #endif return; } #ifdef COMPAT if (inode < inode1) continue; #endif errno = 0; if ((dp = get_inode(fd, super, inode)) && !isfree(super, dp)) { printf("%s\t", user(DIP(super, dp, di_uid))->name); /* now skip whitespace */ while ((c = getchar()) == ' ' || c == '\t'); /* and print out the remainder of the input line */ while (c != EOF && c != '\n') { putchar(c); c = getchar(); } putchar('\n'); inode1 = inode; } else { if (errno) err(1, "%s", name); /* skip this line */ while ((c = getchar()) != EOF && c != '\n') ; } if (c == EOF) break; } }
/** * Put item to place with mouse. * @return 1 if successful, 0 otherwise. */ int Place::mdeselect(Item *it, int scr_x, int scr_y) { if ((mouse_x > scr_x + gx) && (mouse_x < scr_x + gx + width * 16)) if ((mouse_y > scr_y + gy) && (mouse_y < scr_y + gy + height * 15)) { int x2 = (mouse_x - (scr_x + gx) - (it->obdata_width() - 1) * 8) / 16 + viscol; int y2 = (mouse_y - (scr_y + gy) - (it->obdata_height() - 1) * 8) / 15; //text_mode(0); //textprintf(screen, font, 1, 150, 1, "x=%d y=%d", x2, y2); if (isfree(x2, y2) && isfit(it, x2, y2)) { put(it, x2, y2); return 1; } } return 0; }
Click cmatch(Click c, int dtop) { Click lc; lc.d = dtop; do { for(lc.y = 0; lc.y < Ly; lc.y++) for(lc.x = 0; lc.x < Lx; lc.x++) if(level.board[lc.d][lc.x][lc.y].which == TL && isfree(lc) && !eqcl(c, lc) && level.board[c.d][c.x][c.y].type == level.board[lc.d][lc.x][lc.y].type) return lc; } while(--lc.d >= 0); return NC; }
void hint(void) { int d = 0, x = 0, y = 0; Brick *b = nil; if(level.c.d != -1) { if((b = bmatch(level.c)) != nil) { d = level.c.d; x = level.c.x; y = level.c.y; } } else for(d = Depth - 1; d >= 0; d--) for(y = 0; y < Ly; y++) for(x = 0; x < Lx; x++) if(level.board[d][x][y].which == TL && isfree(Cl(d,x,y)) && (b = bmatch(Cl(d,x,y))) != nil) goto Matched; Matched: if (b == nil) return; level.board[d][x][y].clicked = 1; b->clicked = 1; b->redraw = 1; updatelevel(); sleep(500); if(level.c.d == -1) level.board[d][x][y].clicked = 0; b->clicked = 0; b->redraw = 1; updatelevel(); sleep(500); level.board[d][x][y].clicked = 1; b->clicked = 1; b->redraw = 1; updatelevel(); sleep(500); if(level.c.d == -1) level.board[d][x][y].clicked = 0; b->clicked = 0; b->redraw = 1; updatelevel(); }
void clearlevel(void) { Click c, cm; for(c.d = Depth - 1; c.d >= 0; c.d--) for(c.y = 0; c.y < Ly; c.y++) for(c.x = 0; c.x < Lx; c.x++) if(level.board[c.d][c.x][c.y].which == TL && isfree(c)) { cm = cmatch(c, c.d); if(cm.d != -1) { clearbrick(cm); clearbrick(c); updatelevel(); clearlevel(); } } }
static int getiopages(int n) { int i, j; lock(&iopagelock); for(i = 0; i <= NIOPAGES - n; i++){ for(j = 0; j < n; j++) if(!isfree(i + j)) goto next; for(j = 0; j < n; j++) iopages[(i + j) / 8] |= (1 << ((i + j) % 8)); unlock(&iopagelock); return i; next: ; } panic("out of i/o pages"); return 0; }
static void donames(int fd, struct fs *super, char *name) { int c; ino_t maxino; uintmax_t inode; union dinode *dp; maxino = super->fs_ncg * super->fs_ipg - 1; /* first skip the name of the filesystem */ while ((c = getchar()) != EOF && (c < '0' || c > '9')) while ((c = getchar()) != EOF && c != '\n'); ungetc(c,stdin); while (scanf("%ju", &inode) == 1) { if (inode > maxino) { warnx("illegal inode %ju", inode); return; } errno = 0; if ((dp = get_inode(fd,super,inode)) && !isfree(super, dp)) { printf("%s\t",user(DIP(super, dp, di_uid))->name); /* now skip whitespace */ while ((c = getchar()) == ' ' || c == '\t'); /* and print out the remainder of the input line */ while (c != EOF && c != '\n') { putchar(c); c = getchar(); } putchar('\n'); } else { if (errno) { err(1, "%s", name); } /* skip this line */ while ((c = getchar()) != EOF && c != '\n'); } if (c == EOF) break; } }
void clicked(Point coord) { Click c; Brick *b, *bc; c = findclick(coord); if (c.d == -1) return; b = &level.board[c.d][c.x][c.y]; if(isfree(c)) { if(level.c.d == -1) { level.c = c; b->clicked = 1; b->redraw = 1; } else if(eqcl(c, level.c)) { level.c = NC; b->clicked = 0; b->redraw = 1; } else { bc = &level.board[level.c.d][level.c.x][level.c.y]; if(b->type == bc->type) { clearbrick(c); bc->clicked = 0; clearbrick(level.c); level.c = NC; } else { bc->clicked = 0; bc->redraw = 1; b->clicked = 1; b->redraw = 1; level.c = c; } } updatelevel(); if(!canmove()) done(); } }
static void douser(int fd, struct fs *super, char *name) { ino_t inode, maxino; struct user *usr, *usrs; union dinode *dp; int n; maxino = super->fs_ncg * super->fs_ipg - 1; for (inode = 0; inode < maxino; inode++) { errno = 0; if ((dp = get_inode(fd,super,inode)) && !isfree(super, dp)) uses(DIP(super, dp, di_uid), estimate ? virtualblocks(super, dp) : actualblocks(super, dp), DIP(super, dp, di_atime)); else if (errno) { err(1, "%s", name); } } if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) errx(1, "allocate users"); bcopy(users,usrs,nusers * sizeof(struct user)); sortusers(usrs); for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { printf("%5d",SIZE(usr->space)); if (count) printf("\t%5ld",usr->count); printf("\t%-8s",usr->name); if (unused) printf("\t%5d\t%5d\t%5d", SIZE(usr->spc30), SIZE(usr->spc60), SIZE(usr->spc90)); printf("\n"); } free(usrs); }
void light(Point coord) { Click c = findclick(coord); if (c.d == -1) return; if(eqcl(level.l, c)) return; if (level.l.d != -1) { level.board[level.l.d][level.l.x][level.l.y].redraw = 1; level.l = NC; } if(isfree(c)) { level.l = c; level.board[c.d][c.x][c.y].redraw = 1; } updatelevel(); }
void* malloc(size_t n) { int i, cont; int nwrap; uint32_t *ref; void *v; if (mptr == 0) mptr = mbegin; n = ROUNDUP(n, 4); if (n >= MAXMALLOC) return 0; if ((uintptr_t) mptr % PGSIZE){ /* * we're in the middle of a partially * allocated page - can we add this chunk? * the +4 below is for the ref count. */ ref = (uint32_t*) (ROUNDUP(mptr, PGSIZE) - 4); if ((uintptr_t) mptr / PGSIZE == (uintptr_t) (mptr + n - 1 + 4) / PGSIZE) { (*ref)++; v = mptr; mptr += n; return v; } /* * stop working on this page and move on. */ free(mptr); /* drop reference to this page */ mptr = ROUNDDOWN(mptr + PGSIZE, PGSIZE); } /* * now we need to find some address space for this chunk. * if it's less than a page we leave it open for allocation. * runs of more than a page can't have ref counts so we * flag the PTE entries instead. */ nwrap = 0; while (1) { if (isfree(mptr, n + 4)) break; mptr += PGSIZE; if (mptr == mend) { mptr = mbegin; if (++nwrap == 2) return 0; /* out of address space */ } } /* * allocate at mptr - the +4 makes sure we allocate a ref count. */ for (i = 0; i < n + 4; i += PGSIZE){ cont = (i + PGSIZE < n + 4) ? PTE_CONTINUED : 0; if (sys_page_alloc(0, mptr + i, PTE_P|PTE_U|PTE_W|cont) < 0){ for (; i >= 0; i -= PGSIZE) sys_page_unmap(0, mptr + i); return 0; /* out of physical memory */ } } ref = (uint32_t*) (mptr + i - 4); *ref = 2; /* reference for mptr, reference for returned block */ v = mptr; mptr += n; return v; }
static void dofsizes(int fd, struct fs *super, char *name) { ino_t inode, maxino; union dinode *dp; daddr_t sz, ksz; struct fsizes *fp, **fsp; int i; maxino = super->fs_ncg * super->fs_ipg - 1; #ifdef COMPAT if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) err(1, "alloc fsize structure"); #endif /* COMPAT */ for (inode = 0; inode < maxino; inode++) { errno = 0; if ((dp = get_inode(fd, super, inode)) #ifdef COMPAT && ((DIP(super, dp, di_mode) & IFMT) == IFREG || (DIP(super, dp, di_mode) & IFMT) == IFDIR) #else /* COMPAT */ && !isfree(super, dp) #endif /* COMPAT */ ) { sz = estimate ? virtualblocks(super, dp) : actualblocks(super, dp); #ifdef COMPAT if (sz >= FSZCNT) { fsizes->fsz_count[FSZCNT-1]++; fsizes->fsz_sz[FSZCNT-1] += sz; } else { fsizes->fsz_count[sz]++; fsizes->fsz_sz[sz] += sz; } #else /* COMPAT */ ksz = SIZE(sz); for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { if (ksz < fp->fsz_last) break; } if (!fp || ksz < fp->fsz_first) { if (!(fp = (struct fsizes *) malloc(sizeof(struct fsizes)))) { err(1, "alloc fsize structure"); } fp->fsz_next = *fsp; *fsp = fp; fp->fsz_first = (ksz / FSZCNT) * FSZCNT; fp->fsz_last = fp->fsz_first + FSZCNT; for (i = FSZCNT; --i >= 0;) { fp->fsz_count[i] = 0; fp->fsz_sz[i] = 0; } } fp->fsz_count[ksz % FSZCNT]++; fp->fsz_sz[ksz % FSZCNT] += sz; #endif /* COMPAT */ } else if (errno) err(1, "%s", name); } sz = 0; for (fp = fsizes; fp; fp = fp->fsz_next) { for (i = 0; i < FSZCNT; i++) { if (fp->fsz_count[i]) printf("%d\t%d\t%lld\n", fp->fsz_first + i, fp->fsz_count[i], SIZE(sz += fp->fsz_sz[i])); } } }