void batching_add_point_bitmap(primitive_batch *batch, vertex *position, float rad, float angle, float depth) { Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS); float radius = rad; radius *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad vec3d PNT(position->world); vec3d fvec; // get the direction from the point to the eye vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); // move the center of the sprite based on the depth parameter if ( depth != 0.0f ) vm_vec_scale_add(&PNT, &PNT, &fvec, depth); batch_vertex new_particle; vec3d up; vm_rot_point_around_line(&up, &vmd_y_vector, angle, &vmd_zero_vector, &vmd_z_vector); new_particle.position = position->world; new_particle.radius = radius; new_particle.uvec = up; batch->add_point_sprite(&new_particle); }
void batching_add_point_bitmap(primitive_batch *batch, vertex *position, int orient, float rad, float depth) { Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS); float radius = rad; radius *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad vec3d PNT(position->world); vec3d fvec; // get the direction from the point to the eye vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); // move the center of the sprite based on the depth parameter if ( depth != 0.0f ) vm_vec_scale_add(&PNT, &PNT, &fvec, depth); batch_vertex new_particle; vec3d up = {{{ 0.0f, 1.0f, 0.0f }}}; new_particle.position = position->world; new_particle.radius = radius; int direction = orient % 4; switch ( direction ) { case 0: up.xyz.x = 0.0f; up.xyz.y = 1.0f; up.xyz.z = 0.0f; break; case 1: up.xyz.x = 0.0f; up.xyz.y = -1.0f; up.xyz.z = 0.0f; break; case 2: up.xyz.x = -1.0f; up.xyz.y = 0.0f; up.xyz.z = 0.0f; break; case 3: up.xyz.x = 1.0f; up.xyz.y = 0.0f; up.xyz.z = 0.0f; break; } new_particle.uvec = up; batch->add_point_sprite(&new_particle); }
void InitStuff (void) { glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* initialize the join style here */ gleSetJoinStyle (TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP); RAD (1.0); COL (0.0, 0.0, 0.0); PNT (-6.0, 6.0, 0.0); RAD (1.0); COL (0.0, 0.8, 0.3); PNT (6.0, 6.0, 0.0); RAD (3.0); COL (0.8, 0.3, 0.0); PNT (6.0, -6.0, 0.0); RAD (0.5); COL (0.2, 0.3, 0.9); PNT (-6.0, -6.0, 0.0); RAD (2.0); COL (0.2, 0.8, 0.5); PNT (-6.0, 6.0, 0.0); RAD (1.0); COL (0.0, 0.0, 0.0); PNT (6.0, 6.0, 0.0); }
void XArc::Initial() { m_ObjectType = OBJECT_ARC; m_Name = "Arc";// check if it's correct m_Color = 7; m_bShow = true; m_BndBox.Reset(); m_DispType = 1; m_bObjChanged = true; m_DelFlag = true; m_Cen = PNT(0,0,0); m_StartPt = m_Cen; m_EndPt = m_Cen; }
void gc_init(void) { hbase = (uint8_t *)GC_ALIGN_SIZE((uint32_t)&__heap_base__); hend = (uint8_t *)GC_ALIGN_PREV_SIZE((uint32_t)&__heap_end__); hfreemem = (uint32_t)(hend - hbase); hedge = hbase; GCH_SIZE_SET(PNT(hedge), 0xffff); hblocks = 0; hfblocks = 1; _phead = NULL; memset(_gcheaps, 0, sizeof(_gcheaps)); memset(heapblocks, 0, sizeof(heapblocks)); GCH_NEXT_SET(hbase, hbase); //debug("GC Init:\r\n"); //debug("- start at: %x\r\n", hbase); //debug("- end at: %x\r\n", hend); //debug("- heaps: %i %i\n", GC_HEAPS, sizeof(_gcheaps)); }
void geometry_shader_batcher::draw_bitmap(vertex *position, int orient, float rad, float depth) { rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad vec3d PNT(position->world); vec3d fvec; // get the direction from the point to the eye vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); // move the center of the sprite based on the depth parameter if ( depth != 0.0f ) vm_vec_scale_add(&PNT, &PNT, &fvec, depth); particle_pnt new_particle; vec3d up = {{{0.0f, 1.0f, 0.0f}}}; new_particle.position = position->world; new_particle.size = rad; int direction = orient % 4; if ( direction == 1 ) { up.xyz.x = 0.0f; up.xyz.y = -1.0f; up.xyz.z = 0.0f; } else if ( direction == 2 ) { up.xyz.x = -1.0f; up.xyz.y = 0.0f; up.xyz.z = 0.0f; } else if ( direction == 3 ) { up.xyz.x = 1.0f; up.xyz.y = 0.0f; up.xyz.z = 0.0f; } new_particle.up = up; vertices.push_back(new_particle); }
void InitStuff (void) { /* initialize the join style here */ gleSetJoinStyle (TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP); COL (0.0, 0.0, 0.0); PNT (-6.0, 6.0, 0.0); COL (0.0, 0.8, 0.3); PNT (6.0, 6.0, 0.0); COL (0.8, 0.3, 0.0); PNT (6.0, -6.0, 0.0); COL (0.2, 0.3, 0.9); PNT (-6.0, -6.0, 0.0); COL (0.2, 0.8, 0.5); PNT (-6.0, 6.0, 0.0); COL (0.0, 0.0, 0.0); PNT (6.0, 6.0, 0.0); }
void batching_add_bitmap_internal(primitive_batch *batch, vertex *pnt, int orient, float rad, color *clr, float depth) { Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS); float radius = rad; rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad vec3d PNT(pnt->world); vec3d p[4]; vec3d fvec, rvec, uvec; batch_vertex verts[6]; // get the direction from the point to the eye vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); // get an up vector in the general direction of what we want uvec = View_matrix.vec.uvec; // make a right vector from the f and up vector, this r vec is exactly what we want, so... vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec); vm_vec_normalize_safe(&rvec); // fix the u vec with it vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec); // move the center of the sprite based on the depth parameter if ( depth != 0.0f ) vm_vec_scale_add(&PNT, &PNT, &fvec, depth); // move one of the verts to the left vm_vec_scale_add(&p[0], &PNT, &rvec, rad); // and one to the right vm_vec_scale_add(&p[2], &PNT, &rvec, -rad); // now move all oof the verts to were they need to be vm_vec_scale_add(&p[1], &p[2], &uvec, rad); vm_vec_scale_add(&p[3], &p[0], &uvec, -rad); vm_vec_scale_add(&p[0], &p[0], &uvec, rad); vm_vec_scale_add(&p[2], &p[2], &uvec, -rad); //move all the data from the vecs into the verts //tri 1 verts[5].position = p[3]; verts[4].position = p[2]; verts[3].position = p[1]; //tri 2 verts[2].position = p[3]; verts[1].position = p[1]; verts[0].position = p[0]; // set up the UV coords if ( orient & 1 ) { // tri 1 verts[5].tex_coord.u = 1.0f; verts[4].tex_coord.u = 0.0f; verts[3].tex_coord.u = 0.0f; // tri 2 verts[2].tex_coord.u = 1.0f; verts[1].tex_coord.u = 0.0f; verts[0].tex_coord.u = 1.0f; } else { // tri 1 verts[5].tex_coord.u = 0.0f; verts[4].tex_coord.u = 1.0f; verts[3].tex_coord.u = 1.0f; // tri 2 verts[2].tex_coord.u = 0.0f; verts[1].tex_coord.u = 1.0f; verts[0].tex_coord.u = 0.0f; } if ( orient & 2 ) { // tri 1 verts[5].tex_coord.v = 1.0f; verts[4].tex_coord.v = 1.0f; verts[3].tex_coord.v = 0.0f; // tri 2 verts[2].tex_coord.v = 1.0f; verts[1].tex_coord.v = 0.0f; verts[0].tex_coord.v = 0.0f; } else { // tri 1 verts[5].tex_coord.v = 0.0f; verts[4].tex_coord.v = 0.0f; verts[3].tex_coord.v = 1.0f; // tri 2 verts[2].tex_coord.v = 0.0f; verts[1].tex_coord.v = 1.0f; verts[0].tex_coord.v = 1.0f; } for (int i = 0; i < 6 ; i++) { verts[i].r = clr->red; verts[i].g = clr->green; verts[i].b = clr->blue; verts[i].a = clr->alpha; verts[i].radius = radius; } batch->add_triangle(&verts[5], &verts[4], &verts[3]); batch->add_triangle(&verts[2], &verts[1], &verts[0]); }
//计算弧线上距离pt最近的点将弧的分割比例 float XArc::Proportion(PNT pt) { PNT Center = m_Cen; PNT Bpt = m_StartPt; PNT Ept = m_EndPt; //平移到原点 pt -= Center; Bpt -= Center; Ept -= Center; //旋转,使圆弧平面的法向量和z轴重合 pt.Transform_nDirLooksasZ(m_Normal); Bpt.Transform_nDirLooksasZ(m_Normal); Ept.Transform_nDirLooksasZ(m_Normal); //pt 在平面上的投影 PNT ProPt(pt[0],pt[1],0); PNT dirBpt = Bpt; dirBpt.Normalize(); PNT dirEpt = Ept; dirEpt.Normalize(); PNT dirPt = ProPt; dirPt.Normalize(); float angleBpt;//始点的逆时针角度 if(dirBpt[1]>0)//一、二象限 angleBpt = acos(dirBpt[0]); else angleBpt = PI*2.0-acos(dirBpt[0]); //旋转使开始点和x轴正向重合 pt.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); Bpt.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); Ept.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); dirPt.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); dirBpt.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); dirEpt.Rotate(PNT(0,0,0),PNT(0,0,1),PI*2.0-angleBpt); float angleEpt;//终点的逆时针角度 if (dirEpt[1]>0) angleEpt = acos(dirEpt[0]); else angleEpt = PI*2.0-acos(dirEpt[0]); float anglePt;//当前点的逆时针角度 if (dirPt[1]>0) anglePt = acos(dirPt[0]); else anglePt = PI*2.0-acos(dirPt[0]); float prop;//分割比例 if(anglePt<angleEpt)//在始点和终点之间 prop = anglePt/angleEpt; else { if(anglePt>(angleEpt/2.0+PI)) prop = 0.0; else prop = 1.0; } return prop; }
void InitStuff (void) { /* initialize the join style here */ gleSetJoinStyle (TUBE_NORM_PATH_EDGE | TUBE_JN_ANGLE ); RAD (0.3); PNT (-4.9, 6.0, 0.0); RAD (0.3); PNT (-4.8, 5.8, 0.0); RAD (0.3); PNT (-3.8, 5.8, 0.0); RAD (0.6); PNT (-3.5, 6.0, 0.0); RAD (0.8); PNT (-3.0, 7.0, 0.0); RAD (0.9); PNT (-2.4, 7.6, 0.0); RAD (1.0); PNT (-1.8, 7.6, 0.0); RAD (1.1); PNT (-1.2, 7.1, 0.0); RAD (1.2); PNT (-0.8, 5.1, 0.0); RAD (1.7); PNT (-0.3, -2.0, 0.0); RAD (1.8); PNT (-0.2, -7.0, 0.0); RAD (2.0); PNT (0.3, -7.8, 0.0); RAD (2.1); PNT (0.8, -8.2, 0.0); RAD (2.25); PNT (1.8, -8.6, 0.0); RAD (2.4); PNT (3.6, -8.6, 0.0); RAD (2.5); PNT (4.5, -8.2, 0.0); RAD (2.6); PNT (4.8, -7.5, 0.0); RAD (2.7); PNT (5.0, -6.0, 0.0); RAD (3.2); PNT (6.4, -2.0, 0.0); RAD (4.1); PNT (6.9, -1.0, 0.0); RAD (4.1); PNT (7.8, 0.5, 0.0); }
//TODO: remove the stack and make a list of used/marked via header!! phead vs ptail void gc_mark() { int i; PObject *obj; debug( "\n\n>>>>>>>MARK started %x\n", _phead); gc_trace(); gc_keep_root(); while (_phead) { obj = _phead; _phead = GCH_NEXT(obj); int tt = PTYPE(obj); switch (tt) { case PBYTEARRAY: case PSHORTARRAY: if (_PMS(obj)->seq) GC_MARK( _PMS(obj)->seq); break; case PLIST: case PTUPLE: { i = PSEQUENCE_ELEMENTS(obj); PObject **objs = PSEQUENCE_OBJECTS(obj); if (objs) { GC_KEEP_MANY(objs, i); if (PSEQUENCE_BUFFER(obj)) { GC_MARK(PSEQUENCE_BUFFER(obj)); } } } break; case PFSET: case PSET: case PDICT: { PDict *tmp = (PDict *)obj; int e = 0; HashEntry *ee; while ( (ee = phash_getentry(tmp, e++)) != NULL ) { GC_KEEP_NOTNULL(ee->key); if (tt == PDICT) GC_KEEP_NOTNULL(ee->value); } if (tmp->entry) GC_MARK(tmp->entry); } break; case PFUNCTION: { PFunction *tmp = (PFunction *)obj; if (tmp->defargs) GC_KEEP_MANY(tmp->storage, tmp->defargs); //TODO: the following can be optimized by avoiding the check on names... //and use macros to access function fields for portability... if (tmp->defkwargs) GC_KEEP_MANY(tmp->storage + tmp->defargs, 2 * tmp->defkwargs); if (PCODE_CELLVARS(PCODE_MAKE(tmp->codeobj))) { obj = (PObject *)PFUNCTION_GET_CLOSURE(tmp); GC_KEEP(obj); //if (obj) // gc_keep_cells((PTuple *)obj); } } break; case PMETHOD: { PMethod *tmp = (PMethod *)obj; GC_KEEP(tmp->self); GC_KEEP(tmp->fn); } break; case PCLASS: { PClass *tmp = (PClass *)obj; GC_KEEP(tmp->bases); GC_KEEP(tmp->dict); } break; case PINSTANCE: { PInstance *tmp = (PInstance *)obj; GC_KEEP(tmp->base); GC_KEEP(tmp->dict); } break; case PITERATOR: GC_KEEP( ((PIterator *)obj)->iterable ); break; case PFRAME: { //debug("checking frame %i\n", obj); PFrame *tmp = (PFrame *)obj; PCode *code = PCODE_MAKE(tmp->code); GC_KEEP(tmp->parent); //GC_KEEP(tmp->block); GC_KEEP_MANY(PFRAME_PSTACK(tmp), tmp->sp); GC_KEEP_MANY(PFRAME_PLOCALS(tmp, code), code->nlocals); if (PCODE_HASVARS(code)) GC_KEEP_MANY(PFRAME_VARS(tmp, code), 2); /*if (PCODE_FREEVARS(code)) { obj = PFRAME_TFREEVARS(tmp,code);//(PObject *)PFRAME_FREEVARS(tmp); debug("keeping freevars %x for %x\n", obj, tmp); GC_KEEP(obj); } debug("FRAME %x %i %i\n", tmp, PCODE_CELLVARS(code), PCODE_FREEVARS(code)); if (PCODE_CELLVARS(code)) { obj = (PObject *)PFRAME_CELLVARS(tmp); debug("keeping cells for %x\n", obj); GC_KEEP(obj); //if (obj) // gc_keep_cells((PTuple *)obj); } */ } break; /*case PBLOCK: //debug("checking block %i\n", obj); GC_KEEP(((PBlock *)obj)->next); break; */ case PSYSOBJ: { PSysObject *tmp = (PSysObject *) obj; SYSLOCK(); if (tmp->type == PSYS_TIMER) { GC_KEEP(tmp->sys.timer.fn.fn); GC_KEEP(tmp->sys.timer.fn.args); } SYSUNLOCK(); } break; default: break; } //no need to mark obj. It has already been marked in gc_keep //GC_MARK(obj); } gc_trace(); _phead = NULL; obj = PNT(_vm.thlist); do { PThread *pth = (PThread *)obj; debug( "Scanning thread %x %i for consts %x %i\n", pth, pth->header.flags, pth->cocache, pth->cachesize); for (i = 0; i < pth->cachesize; i++) { PObject *co = pth->cocache[i].obj; if (co && GCH_FLAG(co) != GC_USED) continue; //not marked, not staged, not null, not const_marked: remove it pth->cocache[i].obj = NULL; } obj = PNT(pth->next); } while (obj != PNT(_vm.thlist)); debug( ">>>>>>>MARK stopped\n\n\n"); }
//point - VECtor = point PNT PNT::operator - (VEC v) { double a,b,c; v.Get(&a,&b,&c); return PNT(p[0]-a, p[1]-b, p[2]-c, p[3]); }
//------------------------------------------ //overloaded operators // point + VECtor = point PNT PNT:: operator + (VEC v) { double a,b,c; v.Get(&a,&b,&c); return PNT(a+p[0], b+ p[1], c+p[2], p[3]); }
int __libmcr_k_mx_rem_pio2(double x, double y[]) { double z, w, t, r, fn, y0; double tx[3]; int e0, i, j, nx, n, ix, hx, lx, hr, i0; #ifdef debug int ms[10], mw[10], mx[10], my[10], mz[10], nw = 8, mc[10], nz, mt[10], mr[10], my0[10]; nz = __libmcr_k_mi_rem_pio2(x, my, nw); #endif z = fabs(x); w = z * INVPIO2; hx = HIGH_WORD(x); lx = LOW_WORD(x); ix = hx & 0x7fffffff; /* for |x| <= 1638400 */ if (ix <= 0x41390000) { n = (int) (w + HALF); /* |x| ~ n*pi/2, n < 2^19 */ #ifdef debug printf(" w = %1.20e %08X %08X \n", w, .HIGH_WORD(w), .LOW_WORD(w)); printf(" HALF = %1.20e\n", HALF); printf(" n = %d\n", n); #endif if (ix <= 0x3fe921fa) { y[0] = x; y[1] = 0; return (0); } /* |x| < pi/2 */ fn = (double) n; j = ix >> 20; t = fn * PIO2_1; w = fn * PIO2_1T; /* 1st round good to 85 bit */ r = z - t; i0 = 0; y0 = r - w; hr = HIGH_WORD(r); i = (hr & (~0x80000000)) >> 20; #ifdef debug printf("x = %08X %08X % 1.20e\n", HIGH_WORD(x), LOW_WORD(x), x); printf("n = %d\n", n); printf("nz = %d\n", nz); printf("n*PIO2_1 = %08X %08X % 1.20e\n", HIGH_WORD(t), LOW_WORD(t), t); printf("n*PIO2_1T= %08X %08X % 1.20e\n", HIGH_WORD(w), LOW_WORD(w), w); __libmcr_mi_dtomi(t, mt, nw); __libmcr_mi_dtomi(w, mw, nw); __libmcr_mi_dtomi(z, mz, nw); __libmcr_mm_sub(mz, mt, mr, nw); __libmcr_mm_sub(mr, mw, my0, nw); printf("z - n*PIO2 =\n"); PNT(my); PNT(my0); printf("r = z-t = %08X %08X % 1.20e\n", HIGH_WORD(r), LOW_WORD(r), r); printf("y0= r-w = %08X %08X % 1.20e\n", HIGH_WORD(y0), LOW_WORD(y0), y0); printf("j = %d, i = %d, j-i=%d > 6?\n", j, i, j - i); #endif while ((j - i) >= 7) { /* 7 bit cancellation (insure 78 bits) */ t = fn * PIO2_2[i0]; /* at most five loop is suffice */ z = r; j = i; #ifdef debug printf("Are r-t exact?\n"); printf("r = %08X %08X %1.20e\n", r, r); printf("t = %08X %08X %1.20e\n", t, t); __libmcr_mi_dtomi(t, mt, nw); __libmcr_mi_dtomi(r, mw, nw); __libmcr_mm_sub(mw, mt, mt, nw); #endif r -= t; #ifdef debug __libmcr_mi_dtomi(r, mw, nw); __libmcr_mm_sub(mw, mt, mt, nw); if (mt[2] == 0) printf("Yes.\n"); else printf("No.\n"); #endif w = fn * PIO2_2[i0 + 1]; y0 = r - w; i0 += 2; hr = HIGH_WORD(r); i = (hr & (~0x80000000)) >> 20; #ifdef debug printf("w = %08X %08X %1.20e\n", w, w); printf("y0= %08X %08X %1.20e\n", y0, y0); __libmcr_mi_dtomi(t, mt, nw); __libmcr_mi_dtomi(w, mw, nw); __libmcr_mm_sub(mr, mt, mr, nw); __libmcr_mm_sub(mr, mw, my0, nw); printf("z - n*PIO2[%1d] =\n", i0 + 2); PNT(my); PNT(my0); printf("new j = %d, i = %d, j-i=%d > 5?\n", j, i, j - i); #endif } if (i0 == 0 || (j - i) > 1) { r -= y0; y[0] = y0; y[1] = r - w; } else { t += y0 - z; y[0] = y0; y[1] = -w - t; } #ifdef debug printf("test final sum (n=%d):\n", n); __libmcr_mi_dtomi(y[0], mr, nw); printf("y[0] = % 1.20e ", y[0]); PNT(mr); __libmcr_mi_dtomi(y[1], mt, nw); printf("y[1] = % 1.20e ", y[1]); PNT(mt); __libmcr_mm_add(mr, mt, mt, nw); printf("y0+y1 = % 1.20e ", y[0] + y[1]); PNT(mt); PNT(mt); #endif if (hx < 0) { y[1] = -y[1]; y[0] = -y0; return (-n); } else { return (n); } }
void gc_sweep(void) { PObject *start = (PObject *)hbase; PObject *cur = start; PObject *prev = (PObject *)hedge; uint32_t flags; uint32_t prev_is_free = 0; debug( "\n\n<<<<<<<SWEEP started\n"); /*heapwalk and create free list */ hblocks = 0; hfblocks = 0; hfreemem = 0; while (cur != (PObject *)hedge) { flags = GCH_FLAG(cur); //debug("cur is %x with flag %i\n", cur, flags); switch (flags) { case GC_FREE: /*case GC_USED_UNMARKED:*/ gc_sweep_free: hfreemem += GCH_SIZE(cur); debug("sweeping %x\n", cur); //debug("found free block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur)); if (prev_is_free && (GCH_SIZE(prev) + GCH_SIZE(cur) <= 0xffff)) { /* coalesce */ GCH_SIZE_SET(prev, GCH_SIZE(prev) + GCH_SIZE(cur)); //debug("...coalesced with prev %i~%i size %i\n",prev,cur,GCH_SIZE(prev)); prev_is_free = (GCH_SIZE(prev) < 0xffff); } else { prev_is_free = (GCH_SIZE(cur) < 0xffff); GCH_NEXT_SET(prev, cur); /*unset mark flags. First time, sets hedge->next */ prev = cur; hfblocks++; //debug("...splitted prev %i~%i size %i (%i,%i)\n",prev,cur,GCH_SIZE(prev),hblocks,hfblocks); } break; case GC_USED_UNMARKED: if (PHEADERTYPE(cur) == PSYSOBJ) { if (((PSysObject *)cur)->type == PSYS_TIMER) { //if we are here, timer is not in timers and not reachable...free vos mem _gc_free( ((PSysObject *)cur)->sys.timer.vtm); } else if (((PSysObject *)cur)->type == PSYS_SEMAPHORE){ //if it's a lost semaphore, still active, anything can happen :-o _gc_free( ((PSysObject *)cur)->sys.sem); } } goto gc_sweep_free; case GC_USED_MARKED: prev_is_free = 0; GCH_FLAG_SET(cur, GC_USED); hblocks++; //debug("found marked block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur)); break; case GC_STAGED: /* don't touch flags */ prev_is_free = 0; hblocks++; //debug("found staged block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur)); break; } /* skip current */ cur = (PObject *)(((uint8_t *)(cur)) + GCH_SIZE(cur)); } if (prev_is_free) { /* coalesce with hedge */ hfreemem -= GCH_SIZE(prev); GCH_NEXT_SET(prev, GCH_NEXT(hedge)); hedge = (uint8_t *)prev; //debug("coalesced with hedge\n"); } else { GCH_NEXT_SET(prev, hedge); //debug("not coalesced with hedge\n"); hfblocks++; } debug( "S%i\n", hfreemem); hfreemem += ((uint32_t)hend - (uint32_t)hedge); debug( "S%i\n", hfreemem); GCH_SIZE_SET(PNT(hedge), MIN(0xffff, hfreemem)); gc_trace(); debug( "<<<<<<<<SWEEP stopped (%i,%i)\n\n\n", hblocks, hfblocks); }
//REMEBER TO ZERO EVERYTHING!! PObject *gc_alloc(uint8_t type, uint8_t flags, uint16_t size, uint8_t onheap) { uint16_t tsize; uint16_t bfree; PObject *obj = NULL, *prev, *cur, *next; gc_wait(); PThread *pth = PTHREAD_CURRENT(); #if VM_DEBUG int32_t thid = (pth) ? ((int32_t)(vosThGetId(pth->th))) : -1; #endif tsize = GC_ALIGN_SIZE(size);//size +(GC_ALIGNMENT- size % GC_ALIGNMENT); debug( "> th (%i): >>>>ALLOC %i of %i [f:%i,t:%i,h:%i]\r\n", thid, type, size, hfreemem, tsize, heapblocks); if (hfreemem < tsize) { /* no space, fail */ goto exit_alloc; } else { /* normal mark & sweep */ if (gc_checktime || hfreemem < GC_TRIGGER_MIN) { info( "> th (%i) %x: >>> COLLECTING\r\n", thid, pth); gc_mark(); gc_sweep(); last_collect = _systime_millis; gc_checktime = 0; } next = cur = GCH_NEXT(hedge); prev = PNT(hedge); do { bfree = GCH_SIZE(cur); debug( "* check block %x/%x/%x of size %i/%i\n", cur, prev, hedge, bfree, tsize); if (bfree >= tsize) { /*found free block: split or give whole */ obj = cur; if (bfree - tsize < 16) { debug( "* found full block %x/%x/%x next is %x\n", cur, prev, hedge, GCH_NEXT(cur)); /* don't split */ tsize = bfree; cur = GCH_NEXT(cur); hfblocks--; } else { /* split */ debug( "* found splittable block %x/%x/%x new is %x\n", cur, prev, hedge, PNT(TNP(cur) + tsize)); cur = PNT(TNP(cur) + tsize); //(PObject *)(((uint8_t *)cur) + tsize); if (obj == PNT(hedge)) { debug( "* block is hedge, new hedge is %x\n", cur); hedge = (uint8_t *)cur; GCH_SIZE_SET(PNT(hedge), MIN(0xffff, (uint32_t)(hend - hedge))); if (prev == obj) { //set to self debug( "* block is hedge, no other free blocks\n"); GCH_NEXT_SET(PNT(hedge), PNT(hedge)); //prev = PNT(hedge); break; } else { //set to next of hedge before alloc debug( "* block is hedge, other free blocks, prev is %x so next is still %x\n", prev, GCH_NEXT(obj)); GCH_NEXT_SET(PNT(hedge), GCH_NEXT(obj)); } } else { debug( "* block is not hedge: next is %x\n", GCH_NEXT(obj)); GCH_NEXT_SET(cur, GCH_NEXT(obj)); GCH_SIZE_SET(cur, bfree - tsize); //if cur==hedge np } } //set prev to current debug( "* block allocated, update prev %x setting next to %x\n", prev, cur); GCH_NEXT_SET(prev, cur); break; } else { prev = cur; cur = GCH_NEXT(cur); } } while (cur != next); } if (obj == NULL) { goto exit_alloc; } //zero everything memset(((uint8_t *)obj), 0, tsize); //set on stage if (onheap) { //allocate on the heap list uint16_t heapn = (TNP(obj) - TNP(hbase)) / GC_HEAPSIZE; PObject *gcheap = _gcheaps[heapn]; if (!gcheap) { _gcheaps[heapn] = obj; GCH_HEAP_NEXT_SET(obj, obj); GCH_HEAP_PREV_SET(obj, obj); debug( "alloc %x first on heap %i @ %x\n", obj, heapn, obj); } else { //gcheap = _gcheaps[heapn]; next = GCH_HEAP_NEXT(gcheap); GCH_HEAP_PREV_SET(next, obj); GCH_HEAP_NEXT_SET(gcheap, obj); GCH_HEAP_PREV_SET(obj, gcheap); GCH_HEAP_NEXT_SET(obj, next); debug( "alloc %x,on heap %i @ %x with next %x prev %x\n", obj, heapn, gcheap, next, gcheap); } heapblocks[heapn]++; } else { //allocate to system or thread if (pth) { GCH_NEXT_SET(obj, pth->stage); pth->stage = obj; } GCH_FLAG_SET(obj, GC_STAGED); } //set gc data GCH_SIZE_SET(obj, tsize); obj->header.type = type; obj->header.flags = flags; //statistics hfreemem -= tsize; hblocks++; debug( "alloced %x -> %x <- %x\n", obj, GCH_HEAP_NEXT(obj), GCH_HEAP_PREV(obj)); debug( "> th (%i)%x: end alloc %x->%x %x %x edge %i\n", thid, pth, obj, GCH_NEXT(obj), GCH_FLAG(obj), obj->header.gch.flags, PNTD(hedge)); exit_alloc: //TODO: obj == NULL --> raise system exception: out of memory! //debug(">>>>>ALLOCED %i\r\n", obj); //debug("o %i\n",obj ? 1:0); gc_signal(); //gc_trace(); return obj; }
void batching_add_bitmap_rotated_internal(primitive_batch *batch, vertex *pnt, float angle, float rad, color *clr, float depth) { Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS); float radius = rad; rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad extern float Physics_viewer_bank; angle -= Physics_viewer_bank; if ( angle < 0.0f ) angle += PI2; else if ( angle > PI2 ) angle -= PI2; vec3d PNT(pnt->world); vec3d p[4]; vec3d fvec, rvec, uvec; batch_vertex verts[6]; vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &View_matrix.vec.fvec); vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec); vm_vec_normalize_safe(&rvec); vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec); vm_vec_scale_add(&PNT, &PNT, &fvec, depth); vm_vec_scale_add(&p[0], &PNT, &rvec, rad); vm_vec_scale_add(&p[2], &PNT, &rvec, -rad); vm_vec_scale_add(&p[1], &p[2], &uvec, rad); vm_vec_scale_add(&p[3], &p[0], &uvec, -rad); vm_vec_scale_add(&p[0], &p[0], &uvec, rad); vm_vec_scale_add(&p[2], &p[2], &uvec, -rad); //move all the data from the vecs into the verts //tri 1 verts[5].position = p[3]; verts[4].position = p[2]; verts[3].position = p[1]; //tri 2 verts[2].position = p[3]; verts[1].position = p[1]; verts[0].position = p[0]; //tri 1 verts[5].tex_coord.u = 0.0f; verts[5].tex_coord.v = 0.0f; verts[4].tex_coord.u = 1.0f; verts[4].tex_coord.v = 0.0f; verts[3].tex_coord.u = 1.0f; verts[3].tex_coord.v = 1.0f; //tri 2 verts[2].tex_coord.u = 0.0f; verts[2].tex_coord.v = 0.0f; verts[1].tex_coord.u = 1.0f; verts[1].tex_coord.v = 1.0f; verts[0].tex_coord.u = 0.0f; verts[0].tex_coord.v = 1.0f; for (int i = 0; i < 6 ; i++) { verts[i].r = clr->red; verts[i].g = clr->green; verts[i].b = clr->blue; verts[i].a = clr->alpha; verts[i].radius = radius; } batch->add_triangle(&verts[0], &verts[1], &verts[2]); batch->add_triangle(&verts[3], &verts[4], &verts[5]); }
/* 0----1 |\ | | \ | 3----2 */ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float depth) { float radius = rad; rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad vec3d PNT(pnt->world); vec3d p[4]; vec3d fvec, rvec, uvec; vertex *P = &vert[n_to_render * 3]; float *R = &radius_list[n_to_render * 3]; // get the direction from the point to the eye vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); // get an up vector in the general direction of what we want uvec = View_matrix.vec.uvec; // make a right vector from the f and up vector, this r vec is exactly what we want, so... vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec); vm_vec_normalize_safe(&rvec); // fix the u vec with it vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec); // move the center of the sprite based on the depth parameter if ( depth != 0.0f ) vm_vec_scale_add(&PNT, &PNT, &fvec, depth); // move one of the verts to the left vm_vec_scale_add(&p[0], &PNT, &rvec, rad); // and one to the right vm_vec_scale_add(&p[2], &PNT, &rvec, -rad); // now move all oof the verts to were they need to be vm_vec_scale_add(&p[1], &p[2], &uvec, rad); vm_vec_scale_add(&p[3], &p[0], &uvec, -rad); vm_vec_scale_add(&p[0], &p[0], &uvec, rad); vm_vec_scale_add(&p[2], &p[2], &uvec, -rad); //move all the data from the vecs into the verts //tri 1 g3_transfer_vertex(&P[5], &p[3]); g3_transfer_vertex(&P[4], &p[2]); g3_transfer_vertex(&P[3], &p[1]); //tri 2 g3_transfer_vertex(&P[2], &p[3]); g3_transfer_vertex(&P[1], &p[1]); g3_transfer_vertex(&P[0], &p[0]); // set up the UV coords if ( orient & 1 ) { // tri 1 P[5].texture_position.u = 1.0f; P[4].texture_position.u = 0.0f; P[3].texture_position.u = 0.0f; // tri 2 P[2].texture_position.u = 1.0f; P[1].texture_position.u = 0.0f; P[0].texture_position.u = 1.0f; } else { // tri 1 P[5].texture_position.u = 0.0f; P[4].texture_position.u = 1.0f; P[3].texture_position.u = 1.0f; // tri 2 P[2].texture_position.u = 0.0f; P[1].texture_position.u = 1.0f; P[0].texture_position.u = 0.0f; } if ( orient & 2 ) { // tri 1 P[5].texture_position.v = 1.0f; P[4].texture_position.v = 1.0f; P[3].texture_position.v = 0.0f; // tri 2 P[2].texture_position.v = 1.0f; P[1].texture_position.v = 0.0f; P[0].texture_position.v = 0.0f; } else { // tri 1 P[5].texture_position.v = 0.0f; P[4].texture_position.v = 0.0f; P[3].texture_position.v = 1.0f; // tri 2 P[2].texture_position.v = 0.0f; P[1].texture_position.v = 1.0f; P[0].texture_position.v = 1.0f; } for (int i = 0; i < 6 ; i++) { P[i].r = pnt->r; P[i].g = pnt->g; P[i].b = pnt->b; P[i].a = pnt->a; R[i] = radius; } n_to_render += 2; }
void geometry_batcher::draw_bitmap(vertex *pnt, float rad, float angle, float depth) { float radius = rad; rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad extern float Physics_viewer_bank; angle -= Physics_viewer_bank; if ( angle < 0.0f ) angle += PI2; else if ( angle > PI2 ) angle -= PI2; vec3d PNT(pnt->world); vec3d p[4]; vec3d fvec, rvec, uvec; vertex *P = &vert[n_to_render * 3]; float *R = &radius_list[n_to_render * 3]; vm_vec_sub(&fvec, &View_position, &PNT); vm_vec_normalize_safe(&fvec); vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &View_matrix.vec.fvec); vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec); vm_vec_normalize_safe(&rvec); vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec); vm_vec_scale_add(&PNT, &PNT, &fvec, depth); vm_vec_scale_add(&p[0], &PNT, &rvec, rad); vm_vec_scale_add(&p[2], &PNT, &rvec, -rad); vm_vec_scale_add(&p[1], &p[2], &uvec, rad); vm_vec_scale_add(&p[3], &p[0], &uvec, -rad); vm_vec_scale_add(&p[0], &p[0], &uvec, rad); vm_vec_scale_add(&p[2], &p[2], &uvec, -rad); //move all the data from the vecs into the verts //tri 1 g3_transfer_vertex(&P[5], &p[3]); g3_transfer_vertex(&P[4], &p[2]); g3_transfer_vertex(&P[3], &p[1]); //tri 2 g3_transfer_vertex(&P[2], &p[3]); g3_transfer_vertex(&P[1], &p[1]); g3_transfer_vertex(&P[0], &p[0]); //tri 1 P[5].texture_position.u = 0.0f; P[5].texture_position.v = 0.0f; P[4].texture_position.u = 1.0f; P[4].texture_position.v = 0.0f; P[3].texture_position.u = 1.0f; P[3].texture_position.v = 1.0f; //tri 2 P[2].texture_position.u = 0.0f; P[2].texture_position.v = 0.0f; P[1].texture_position.u = 1.0f; P[1].texture_position.v = 1.0f; P[0].texture_position.u = 0.0f; P[0].texture_position.v = 1.0f; for (int i = 0; i < 6 ; i++) { P[i].r = pnt->r; P[i].g = pnt->g; P[i].b = pnt->b; P[i].a = pnt->a; R[i] = radius; } n_to_render += 2; }
void gc_keep_root(void) { PObject *obj; int i; if (_vmpnt) { //get the root set obj = PNT(_vm.thlist); do { PThread *pth = (PThread *)obj; VThread vth = pth->th; debug( "Scanning thread %x %i\n", pth, pth->header.flags); if (vth && vosThGetStatus(vth) == VTHREAD_INACTIVE) { //terminated, remove from list...it will die if no references remain pth->prev->next = pth->next; pth->next->prev = pth->prev; GCH_FLAG_SET(pth, GC_USED); //free workspace //if PThread has references, it's ok. But it can't be restarted _gc_free(vth); pth->th = NULL; } else { GC_MARK(pth); if (pth->frame) GC_KEEP(pth->frame); } obj = PNT(pth->next); } while (obj != PNT(_vm.thlist)); for (i = 0; i < _vm.nmodules; i++) { PModule *mod = VM_MODULE(i); GC_MARK(mod); if (PMODULE_IS_LOADED(mod)) { GC_KEEP_MANY(mod->globals, mod->nfo.nums.nglobals); } else { GC_KEEP(mod->nfo.frame); } } //-----> irqs could be modifing irq struct here: no worries SYSLOCK(); //slots & irqstack for (i = 0; i < _vm.irqn; i++) { GC_KEEP(_vm.irqstack[i].fn); GC_KEEP_NOTNULL(_vm.irqstack[i].args); } for (i = 0; i < EXT_SLOTS; i++) { if (_vm.irqslots[0][i].fn) { GC_KEEP(_vm.irqslots[0][i].fn); GC_KEEP_NOTNULL(_vm.irqslots[0][i].args); } if (_vm.irqslots[1][i].fn) { GC_KEEP(_vm.irqslots[1][i].fn); GC_KEEP_NOTNULL(_vm.irqslots[1][i].args); } } if (_vm.irqcur) { GC_KEEP(_vm.irqcur->fn); GC_KEEP_NOTNULL(_vm.irqcur->args); } if (_vm.timers) { obj = _vm.timers; do { GC_KEEP(obj); obj = (PObject *)((PSysObject *)obj)->sys.timer.next; } while (obj != _vm.timers); } SYSUNLOCK(); //-----> irq could be modifing irq struct here: // - it can add something to irqslots: np, the objects added must be in an active frame (gc lock is on, no new frame can be created) // - it can add something to irqstack from pin irq: np, the objects are sitting in irqslots // - it can add something to irqstack from timers: that timer was in the timer list, so it is already kept // - it can be the irqthread at 2 different times: // - it modifies _vm.irqcur after putting it in a new frame: if happens up there, np. if happens now, already kept // - it does _vm.irqn--: if happens up there, the removed irqfn is in irqcur. if happens here, already kept } }