/* * feye.c * Sierpinsky * * Created by Victor Grishchenko on 2/11/09. * Copyright 2009 Delft Technical University. All rights reserved. * */ #include #include #include #include "feye.h" #define FEYE_BITS_SIZE ((FEYE_MAX_CHUNK+1)*sizeof(sbitint)) feye feye_new (mlat focus) { feye ret; assert(mlat_height(focus)<=6); focus=mlat_parentn(focus,6-mlat_height(focus)); ret.focus = focus; ret.bits = (sbitint*) malloc(FEYE_BITS_SIZE); memset(ret.bits,0,FEYE_BITS_SIZE); return ret; } feyeloc_t feye_location (const feye bm, mlat bit) { feyeloc_t ret; uint8_t height = mlat_height(bit); mlat cmprnt = mlat_common_parent(bit,bm.focus); uint8_t commht = mlat_height(cmprnt); ret.chunk = commht <= SBIT_HEIGHT ? 0 : commht-SBIT_HEIGHT; int elevation = height - ret.chunk + (ret.chunk?1:0); mlat chunktop = mlat_parentn(bit,6-elevation); if (ret.chunk && height==commht) ret.position = FEYE_AIR; else if (elevation<0) ret.position = FEYE_WATER; else if (elevation) ret.position = FEYE_MOUNTAIN; else ret.position = FEYE_GROUND; switch (ret.position) { case FEYE_AIR: ret.mask = SBIT_1CHUNK; break; case FEYE_WATER: bit = mlat_parentn(bit,-elevation); // no break case FEYE_MOUNTAIN: case FEYE_GROUND: ret.mask = SBIT_BLOCK_MASKS[mlat_height(chunktop)%SBIT_HEIGHT][mlat_rel64(chunktop,bit)]; } return ret; } int feye_set (feye bm, mlat bit) { feyeloc_t loc = feye_location(bm,bit); switch (loc.position) { case FEYE_WATER: return 0; case FEYE_AIR: for(uint8_t i=0; i<=loc.chunk; i++) bm.bits[i] = SBIT_1CHUNK; return 1; case FEYE_GROUND: case FEYE_MOUNTAIN: bm.bits[loc.chunk] |= loc.mask; return 1; } exit(-1001); } int feye_get (feye bm, mlat bit) { feyeloc_t loc = feye_location(bm,bit); switch (loc.position) { case FEYE_WATER: case FEYE_GROUND: case FEYE_MOUNTAIN: return (bm.bits[loc.chunk]&loc.mask) == loc.mask; case FEYE_AIR: for(uint8_t i=0; i<=loc.chunk; i++) if (bm.bits[i] != SBIT_1CHUNK) return 0; return 1; } exit(-1001); } feye feye_refocus (feye a, mlat new_focus) { uint8_t nfhe = mlat_height(new_focus); if (nfhe<6) new_focus = mlat_parentn(new_focus,6-nfhe); else new_focus = mlat_leftn(new_focus, nfhe-6); mlat cparent = mlat_common_parent (a.focus,new_focus); feye ret = feye_new(new_focus); if (cparent==new_focus) { memcpy(ret.bits, a.bits, FEYE_BITS_SIZE); return ret; } int cheight = mlat_height(cparent); sbitint gather = a.bits[0]; for(int h=SBIT_HEIGHT+1; hSBIT_HEIGHT; h--) { sbit2int lr = sbit_split(tosp,h); if (mlat_is_left_at(new_focus,h-1)) spread[h-SBIT_HEIGHT] = lr.right, tosp = lr.left; else spread[h-SBIT_HEIGHT] = lr.left, tosp = lr.right; } spread[0] = tosp; for(int i=0; i