mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-11-04 07:43:02 +00:00 
			
		
		
		
	tailored allocation, and increased MAX_EDGE to 14
This commit is contained in:
		@@ -410,7 +410,8 @@ struct hrmap_archimedean : hrmap {
 | 
			
		||||
  heptagon *getOrigin() { return origin; }
 | 
			
		||||
 | 
			
		||||
  hrmap_archimedean() {
 | 
			
		||||
    origin = new heptagon;
 | 
			
		||||
    int N0 = isize(current.adjacent[0]);
 | 
			
		||||
    origin = tailored_alloc<heptagon> (N0);
 | 
			
		||||
    origin->s = hsOrigin;
 | 
			
		||||
    origin->emeraldval = 0;
 | 
			
		||||
    origin->zebraval = 0;
 | 
			
		||||
@@ -418,23 +419,21 @@ struct hrmap_archimedean : hrmap {
 | 
			
		||||
    origin->fieldval = 0;
 | 
			
		||||
    origin->rval0 = origin->rval1 = 0;
 | 
			
		||||
    origin->cdata = NULL;
 | 
			
		||||
    origin->c.clear();
 | 
			
		||||
    origin->alt = NULL;
 | 
			
		||||
    origin->distance = 0;
 | 
			
		||||
 | 
			
		||||
    parent_index_of(origin) = 0;
 | 
			
		||||
    id_of(origin) = 0;
 | 
			
		||||
    origin->c7 = newCell(isize(current.adjacent[0]), origin);
 | 
			
		||||
    origin->c7 = newCell(N0, origin);
 | 
			
		||||
    
 | 
			
		||||
    heptagon *alt = NULL;
 | 
			
		||||
    
 | 
			
		||||
    if(hyperbolic) {
 | 
			
		||||
      dynamicval<eGeometry> g(geometry, gNormal); 
 | 
			
		||||
      alt = new heptagon;
 | 
			
		||||
      alt = tailored_alloc<heptagon> (S7);
 | 
			
		||||
      alt->s = hsOrigin;
 | 
			
		||||
      alt->emeraldval = 0;
 | 
			
		||||
      alt->zebraval = 0;
 | 
			
		||||
      alt->c.clear();
 | 
			
		||||
      alt->distance = 0;
 | 
			
		||||
      alt->c7 = NULL;
 | 
			
		||||
      alt->alt = alt;
 | 
			
		||||
@@ -491,7 +490,7 @@ transmatrix adjcell_matrix(heptagon *h, int d);
 | 
			
		||||
 | 
			
		||||
heptagon *build_child(heptspin p, pair<int, int> adj) {
 | 
			
		||||
  indenter ind;
 | 
			
		||||
  auto h = buildHeptagon1(new heptagon, p.at, p.spin, hstate(1), 0);
 | 
			
		||||
  auto h = buildHeptagon1(tailored_alloc<heptagon> (isize(current.adjacent[adj.first])), p.at, p.spin, hstate(1), 0);
 | 
			
		||||
  SDEBUG( printf("NEW %p.%d ~ %p.0\n", p.at, p.spin, h); )
 | 
			
		||||
  id_of(h) = adj.first;
 | 
			
		||||
  parent_index_of(h) = adj.second;
 | 
			
		||||
 
 | 
			
		||||
@@ -741,7 +741,7 @@ bool buildBarrierNowall(cell *c, eLand l2, int forced_dir) {
 | 
			
		||||
  bool warpv = warped_version(c->land, l2);
 | 
			
		||||
  if(warpv && !archimedean && !pseudohept(c)) return false;
 | 
			
		||||
  
 | 
			
		||||
  int ds[8];
 | 
			
		||||
  int ds[MAX_EDGE];
 | 
			
		||||
  for(int i=0; i<c->type; i++) ds[i] = i;
 | 
			
		||||
  for(int j=0; j<c->type; j++) swap(ds[j], ds[hrand(j+1)]);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -202,13 +202,12 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
 | 
			
		||||
    if(polarb50(c) != 1) return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  heptagon *alt = new heptagon;
 | 
			
		||||
  heptagon *alt = tailored_alloc<heptagon> (S7);
 | 
			
		||||
  allmaps.push_back(newAltMap(alt));
 | 
			
		||||
//printf("new alt {%p}\n", alt);
 | 
			
		||||
  alt->s = firststate;
 | 
			
		||||
  alt->emeraldval = 0;
 | 
			
		||||
  alt->zebraval = 0;
 | 
			
		||||
  alt->c.clear();
 | 
			
		||||
  alt->distance = 0;
 | 
			
		||||
  alt->c7 = NULL;
 | 
			
		||||
  alt->alt = alt;
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@ namespace binary {
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
 | 
			
		||||
    auto h = buildHeptagon1(new heptagon, parent, d, hsOrigin, d1);
 | 
			
		||||
    auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1);
 | 
			
		||||
    h->distance = parent->distance + delta;
 | 
			
		||||
    h->c7 = newCell(t, h);
 | 
			
		||||
    h->cdata = NULL;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								cell.cpp
									
									
									
									
									
								
							@@ -22,10 +22,9 @@ int cellcount = 0;
 | 
			
		||||
void initcell(cell *c); // from game.cpp
 | 
			
		||||
 | 
			
		||||
cell *newCell(int type, heptagon *master) {
 | 
			
		||||
  cell *c = new cell;
 | 
			
		||||
  cell *c = tailored_alloc<cell> (type);
 | 
			
		||||
  c->type = type;
 | 
			
		||||
  c->master = master;
 | 
			
		||||
  for(int i=0; i<MAX_EDGE; i++) c->move(i) = NULL;
 | 
			
		||||
  initcell(c);
 | 
			
		||||
  return c;
 | 
			
		||||
  }
 | 
			
		||||
@@ -52,7 +51,7 @@ hrmap *newAltMap(heptagon *o) { return new hrmap_alternate(o); }
 | 
			
		||||
 | 
			
		||||
hrmap_hyperbolic::hrmap_hyperbolic() {
 | 
			
		||||
  // printf("Creating hyperbolic map: %p\n", this);
 | 
			
		||||
  origin = new heptagon;
 | 
			
		||||
  origin = tailored_alloc<heptagon> (S7);
 | 
			
		||||
  heptagon& h = *origin;
 | 
			
		||||
  h.s = hsOrigin;
 | 
			
		||||
  h.emeraldval = a46 ? 0 : 98;
 | 
			
		||||
@@ -61,7 +60,6 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
 | 
			
		||||
  h.fieldval = 0;
 | 
			
		||||
  h.rval0 = h.rval1 = 0;
 | 
			
		||||
  h.cdata = NULL;
 | 
			
		||||
  h.c.clear();
 | 
			
		||||
  h.alt = NULL;
 | 
			
		||||
  h.distance = 0;
 | 
			
		||||
  isnonbitrunc = nonbitrunc;
 | 
			
		||||
@@ -109,7 +107,7 @@ struct hrmap_spherical : hrmap {
 | 
			
		||||
      h.rval0 = h.rval1 = 0;
 | 
			
		||||
      h.alt = NULL;
 | 
			
		||||
      h.cdata = NULL;
 | 
			
		||||
      h.c.clear();
 | 
			
		||||
      h.c.fullclear();
 | 
			
		||||
      h.fieldval = i;
 | 
			
		||||
      if(!irr::on) h.c7 = newCell(S7, &h);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -69,14 +69,13 @@ template<class... T> auto iprintf(T... t) { for(int i=0; i<indent; i++) putchar(
 | 
			
		||||
heptagon *buildHeptagon1(heptagon *h, heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
 | 
			
		||||
  h->alt = NULL;
 | 
			
		||||
  h->s = s;
 | 
			
		||||
  h->c.clear();
 | 
			
		||||
  h->c.connect(pard, parent, d, false);
 | 
			
		||||
  h->cdata = NULL;
 | 
			
		||||
  return h;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
 | 
			
		||||
  heptagon *h = buildHeptagon1(new heptagon, parent, d, s, pard, fixdistance);
 | 
			
		||||
  heptagon *h = buildHeptagon1(tailored_alloc<heptagon> (S7), parent, d, s, pard, fixdistance);
 | 
			
		||||
  if(binarytiling || archimedean) return h;
 | 
			
		||||
  if(parent->c7) {
 | 
			
		||||
    if(irr::on)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								hyper.h
									
									
									
									
									
								
							@@ -320,30 +320,43 @@ struct gcell {
 | 
			
		||||
#define NOBARRIERS 15
 | 
			
		||||
#define MODFIXER 10090080
 | 
			
		||||
 | 
			
		||||
#define MAX_EDGE 12
 | 
			
		||||
#define MAX_EDGE 14
 | 
			
		||||
 | 
			
		||||
template<class T> struct walker;
 | 
			
		||||
 | 
			
		||||
template<class T> struct connection_table {
 | 
			
		||||
 | 
			
		||||
  // Assumption: class T has a field c of type connection_table<T>.
 | 
			
		||||
 | 
			
		||||
  // NOTE: since aconnection_table may be allocated with
 | 
			
		||||
  // less than MAX_EDGE neighbors (see tailored_alloc),
 | 
			
		||||
  // the order of fields matters.
 | 
			
		||||
 | 
			
		||||
  unsigned char spintable[6];
 | 
			
		||||
  unsigned short mirrortable;
 | 
			
		||||
  // neighbors; move[0] always goes towards origin, and then we go clockwise
 | 
			
		||||
  T* move_table[MAX_EDGE];
 | 
			
		||||
  unsigned char spintable_extra[2];
 | 
			
		||||
  
 | 
			
		||||
  T* full() { T* x; return (T*)((char*)this - ((char*)(&(x->c)) - (char*)x)); }
 | 
			
		||||
  unsigned char& get_spinchar(int d) {
 | 
			
		||||
    if(d < 12) return spintable[d>>1];
 | 
			
		||||
    else return spintable_extra[(d-12)>>1];
 | 
			
		||||
    }
 | 
			
		||||
  void setspin(int d, int spin, bool mirror) { 
 | 
			
		||||
    spintable[d>>1] &= ~(15 << ((d&1) << 2));
 | 
			
		||||
    spintable[d>>1] |= spin << ((d&1) << 2);
 | 
			
		||||
    unsigned char& c = get_spinchar(d);
 | 
			
		||||
    c &= ~(15 << ((d&1) << 2));
 | 
			
		||||
    c |= spin << ((d&1) << 2);
 | 
			
		||||
    if(mirror) mirrortable |= (1 << d);
 | 
			
		||||
    else mirrortable &=~ (1 << d);
 | 
			
		||||
    }
 | 
			
		||||
  // we are spin(i)-th neighbor of move[i]
 | 
			
		||||
  int spin(int d) { return (spintable[d>>1] >> ((d&1)<<2)) & 15; }
 | 
			
		||||
  int spin(int d) { return (get_spinchar(d) >> ((d&1)<<2)) & 15; }
 | 
			
		||||
  bool mirror(int d) { return (mirrortable >> d) & 1; }  
 | 
			
		||||
  int fix(int d) { return (d + MODFIXER) % full()->degree(); }
 | 
			
		||||
  T*& modmove(int i) { return move(fix(i)); }
 | 
			
		||||
  T*& move(int i) { return move_table[i]; }
 | 
			
		||||
  unsigned char modspin(int i) { return spin(fix(i)); }
 | 
			
		||||
  void clear() { 
 | 
			
		||||
  void fullclear() { 
 | 
			
		||||
    for(int i=0; i<MAX_EDGE; i++) move_table[i] = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  void connect(int d0, T* c1, int d1, bool m) {
 | 
			
		||||
@@ -357,6 +370,29 @@ template<class T> struct connection_table {
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Allocate a class T with a connection_table, but 
 | 
			
		||||
// with only `degree` connections. Also set yet
 | 
			
		||||
// unknown connections to NULL.
 | 
			
		||||
 | 
			
		||||
// Generating the hyperbolic world consumes lots of
 | 
			
		||||
// RAM, so we really need to be careful on low memory devices. 
 | 
			
		||||
 | 
			
		||||
template<class T> T* tailored_alloc(int degree) {
 | 
			
		||||
  const T* sample = (T*) °ree;
 | 
			
		||||
  T* result;
 | 
			
		||||
#ifndef NO_TAILORED_ALLOC
 | 
			
		||||
  if(degree <= 12) {
 | 
			
		||||
    int b = (char*)&sample->c.move_table[degree] - (char*) sample;
 | 
			
		||||
    result = (T*) new char[b];
 | 
			
		||||
    new (result) T();
 | 
			
		||||
    }
 | 
			
		||||
  else 
 | 
			
		||||
#endif
 | 
			
		||||
    result = new T;
 | 
			
		||||
  for(int i=0; i<degree; i++) result->c.move_table[i] = NULL;
 | 
			
		||||
  return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
static const struct wstep_t { wstep_t() {} } wstep;
 | 
			
		||||
static const struct wmirror_t { wmirror_t() {}} wmirror;
 | 
			
		||||
static const struct rev_t { rev_t() {} } rev;
 | 
			
		||||
@@ -415,8 +451,6 @@ template<class T> struct walker {
 | 
			
		||||
  walker<T> mirrorat(int d) { return walker<T> (at, at->c.fix(d+d - spin), !mirrored); }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
inline int fix42(int a) { return (a+MODFIXER)% S42; }
 | 
			
		||||
 | 
			
		||||
struct cell;
 | 
			
		||||
 | 
			
		||||
// automaton state
 | 
			
		||||
@@ -455,6 +489,11 @@ struct heptagon {
 | 
			
		||||
  ~heptagon () { heptacount--; }
 | 
			
		||||
  heptagon *cmove(int d) { return createStep(this, d); }
 | 
			
		||||
  inline int degree(); 
 | 
			
		||||
 | 
			
		||||
  // prevent accidental copying
 | 
			
		||||
  heptagon(const heptagon&) = delete;
 | 
			
		||||
  heptagon& operator=(const heptagon&) = delete;
 | 
			
		||||
  // do not add any fields after connection_table (see tailored_alloc)
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
struct cell : gcell {
 | 
			
		||||
@@ -472,6 +511,12 @@ struct cell : gcell {
 | 
			
		||||
  cell*& move(int d) { return c.move(d); }
 | 
			
		||||
  cell*& modmove(int d) { return c.modmove(d); }
 | 
			
		||||
  cell* cmove(int d) { return createMov(this, d); }
 | 
			
		||||
  cell() {}
 | 
			
		||||
 | 
			
		||||
  // prevent accidental copying
 | 
			
		||||
  cell(const cell&) = delete;
 | 
			
		||||
  heptagon& operator=(const cell&) = delete;
 | 
			
		||||
  // do not add any fields after connection_table (see tailored_alloc)
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
int heptagon::degree() { if(archimedean) return c7->type; else return S7; }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user