bool extbmp_is_member( extbmp_t *ebmp, word untagged_w ) { /* untagged_w in ebmp ? */ leaf_t *leaf; word first; bool found; unsigned int bit_idx, word_idx, bit_in_word; found = find_leaf_or_fail( ebmp, untagged_w, &leaf, &first ); #if 0 if (found) { word lim = leaf_wordaddr_lim( ebmp, first ); assert2( first <= untagged_w ); assert2( untagged_w < lim ); consolemsg( "extbmp_is_member( ebmp, w=0x%08x )" " found, leaf=0x%08x first=0x%08x lim=0x%08x", untagged_w, leaf, first, lim); } else { consolemsg( "extbmp_is_member( ebmp, w=0x%08x ) unfound", untagged_w ); } #endif if (! found) return FALSE; assert2( first <= untagged_w ); assert2( untagged_w < leaf_wordaddr_lim( ebmp, first )); bit_idx = (untagged_w - first) >> BIT_IDX_SHIFT; word_idx = bit_idx >> BIT_IDX_TO_WORDADDR; bit_in_word = 1 << (bit_idx & BIT_IN_WORD_MASK); return (leaf->bitmap[ word_idx ] & bit_in_word); }
void mem_validate(mem_pool_t *m){ mheader_t *h; //mutex_lock (&m->lock); mheader_t* limit = (mheader_t*)((size_t)m->store+m->size); for (h=(mheader_t*)m->store; h<limit; h=SUCC(h)) { assert2( (h->pool == m) , "bad block $%x[$%x]:$%hx on pool[$%x]\n" , h, h->size , h->magic, h->pool ); assert2( (h->magic == MEMORY_BLOCK_MAGIC) || (h->magic == MEMORY_HOLE_MAGIC) , "$%x[$%x]:bad magic %2s=$%hx\n" , h, h->size, &h->magic, (int)(h->magic) ); assert2( ( (h->size == MEM_ALIGN(h->size)) && (h->size >= (MEM_HSIZE+ SIZEOF_ALIGN)) && (h->size <= ((size_t)limit - (size_t)h) ) ) , "bad block $%x size $%x\n" , h, h->size ); } //mutex_unlock (&m->lock); }
static void assert2_pair_addresses_mapped( msgc_context_t *context, word w ) { { #ifndef NDEBUG2 if (isptr(pair_cdr(w)) && ! gc_is_address_mapped( context->gc, ptrof(pair_cdr(w)), FALSE )) { gc_is_address_mapped( context->gc, ptrof(pair_cdr(w)), TRUE ); consolemsg("unmapped address, pair 0x%08x in gen %d, cdr = 0x%08x", w, gen_of(w), pair_cdr(w)); consolemsg("(gno count: %d)", context->gc->gno_count); assert2(0); } if (isptr(pair_car(w)) && ! gc_is_address_mapped( context->gc, ptrof(pair_car(w)), FALSE )) { gc_is_address_mapped( context->gc, ptrof(pair_car(w)), TRUE ); consolemsg("unmapped address, pair 0x%08x in gen %d, car = 0x%08x", w, gen_of(w), pair_car(w)); consolemsg("(gno count: %d)", context->gc->gno_count); assert2(0); } #endif } }
/* FIXME: Worth optimizing! Pass more than one object to the scanner. */ void rs_enumerate( remset_t *rs, bool (*scanner)( word, void*, unsigned* ), void *data ) { pool_t *ps; word *p, *q; unsigned word_count = 0; unsigned removed_count=0; unsigned scanned = 0; unsigned scanned_all = 0; assert( WORDS_PER_POOL_ENTRY == 2 ); supremely_annoyingmsg( "REMSET @0x%p: scan", (void*)rs ); ps = DATA(rs)->first_pool; while (1) { p = ps->bot; q = ps->top; scanned_all += (q-p)/2; /* Zero entries also */ while (p < q) { if (*p != 0) { #if !GCLIB_LARGE_TABLE /* These attributes not defined then */ #ifndef NDEBUG2 if ( (attr_of(*p) & (MB_ALLOCATED|MB_HEAP_MEMORY)) != (MB_ALLOCATED|MB_HEAP_MEMORY) ) { assert2(attr_of(*p) & MB_ALLOCATED); assert2(attr_of(*p) & MB_HEAP_MEMORY); } #endif #endif if (!scanner( *p, data, &word_count )) { /* Clear the slot by setting the pointer to 0. */ *p = (word)(word*)0; removed_count++; } scanned++; /* Only nonzero entries */ } p += 2; } if (ps == DATA(rs)->curr_pool) break; ps = ps->next; } DATA(rs)->stats.objs_scanned += scanned; DATA(rs)->stats.max_objs_scanned = max( DATA(rs)->stats.max_objs_scanned, scanned ); DATA(rs)->stats.words_scanned += word_count; DATA(rs)->stats.max_words_scanned = max( DATA(rs)->stats.max_words_scanned, word_count ); DATA(rs)->stats.removed += removed_count; rs->live -= removed_count; DATA(rs)->stats.scanned++; supremely_annoyingmsg( "REMSET @0x%x: removed %d elements (total %d).", (word)rs, removed_count, DATA(rs)->stats.removed ); }
void main_part_1(){ assert2( is_derived_from(BarBase, BarDerived), Is_Not_Derived ); assert2( is_derived_from(BarBase, Foo), Is_Not_Derived ); }
bool msgc_object_marked_p( msgc_context_t *context, word obj ) { word bit_idx, word_idx, bit; assert2( isptr( obj ) ); assert2( context->lowest_heap_address <= ptrof( obj ) && ptrof( obj ) < context->highest_heap_address ); bit_idx = (obj - (word)context->lowest_heap_address) >> BIT_IDX_SHIFT; word_idx = bit_idx >> BITS_TO_WORDS; bit = 1 << (bit_idx & BIT_IN_WORD_MASK); return (context->bitmap[ word_idx ] & bit); }
// Load a texture from file SDL_Texture* GraphicsSystem::loadTexture(const std::string& path) { SDL_Surface* loadedSurface = IMG_Load(path.c_str()); const char* errorMessage = "Failed to load image at path '%s'. SDL Error: %s"; assert2(loadedSurface != nullptr, errorMessage, path.c_str(), SDL_GetError()); SDL_Texture* loadedTexture = SDL_CreateTextureFromSurface(_renderer, loadedSurface); assert2(loadedTexture != nullptr, errorMessage, path.c_str(), SDL_GetError()); SDL_FreeSurface(loadedSurface); printf("Texture '%s' loaded successfully.\n", path.c_str()); return loadedTexture; }
static void update_phase_stats_add( gc_mmu_log_t *log, struct event_window *w, struct event_phase_stats *s, unsigned elapsed_real, unsigned elapsed_cpu ) { assert2( s->current_real >= 0 ); assert2( s->current_cpu >= 0 ); s->current_real += elapsed_real; s->current_cpu += elapsed_cpu; assert2( s->current_real >= 0 ); assert2( s->current_cpu >= 0 ); }
/* ChapelDynDispHack.chpl:21 */ static void chpl__init_ChapelDynDispHack(int64_t _ln, c_string _fn) { c_string modFormatStr; c_string modStr; _ref_int32_t refIndentLevel = NULL; int32_t call_tmp; chpl_localeID_t call_tmp2; _ref_chpl_localeID_t ret_to_arg_ref_tmp_ = NULL; chpl_localeID_t call_tmp3; locale call_tmp4 = NULL; int64_t call_tmp5; chpl_bool call_tmp6; if (chpl__init_ChapelDynDispHack_p) { goto _exit_chpl__init_ChapelDynDispHack; } modFormatStr = "%*s\n"; modStr = "ChapelDynDispHack"; printModuleInit(modFormatStr, modStr, INT64(17), _ln, _fn); refIndentLevel = &moduleInitLevel; *(refIndentLevel) += INT64(1); chpl__init_ChapelDynDispHack_p = true; call_tmp = chpl_task_getRequestedSubloc(); ret_to_arg_ref_tmp_ = &call_tmp2; chpl_buildLocaleID(chpl_nodeID, call_tmp, ret_to_arg_ref_tmp_, _ln, _fn); call_tmp3 = chpl__initCopy_chpl_rt_localeID_t(call_tmp2); call_tmp4 = chpl_localeID_to_locale(&call_tmp3, _ln, _fn); call_tmp5 = id(call_tmp4, _ln, _fn); call_tmp6 = (call_tmp5 >= INT64(0)); assert2(call_tmp6, _ln, _fn); *(refIndentLevel) -= INT64(1); _exit_chpl__init_ChapelDynDispHack: ; return; }
bool rs_add_elem_new( remset_t *rs, word w ) { word mask, *tbl, *b, *pooltop, *poollim, tblsize, h; bool overflowed = FALSE; remset_data_t *data = DATA(rs); assert2(! rs_isremembered( rs, w )); pooltop = data->curr_pool->top; poollim = data->curr_pool->lim; tbl = data->tbl_bot; tblsize = data->tbl_lim - tbl; mask = tblsize-1; h = hash_object( w, mask ); if (pooltop == poollim) { handle_overflow( rs, 0, pooltop ); pooltop = data->curr_pool->top; poollim = data->curr_pool->lim; overflowed = TRUE; } *pooltop = w; *(pooltop+1) = tbl[h]; tbl[h] = (word)pooltop; pooltop += 2; data->curr_pool->top = pooltop; data->curr_pool->lim = poollim; data->stats.recorded += 1; rs->live += 1; return overflowed; }
void PlayState::spawnBullet(int count, bool playerFired, int * x, int * y, Path * paths, int * damage, int * spriteChoice) { if (playerFired) { // update global stage bullet counter g_playerStageBulletsTotal += count; PlayerBulletIterator bullets = playerBullets.alloc(count); int bulletCounter = 0; Bullet * toSpawn; while ((toSpawn = bullets.next()) != 0) { toSpawn->setPos(x[bulletCounter], y[bulletCounter]); toSpawn->setPath(paths[bulletCounter]); toSpawn->setDamage(damage[bulletCounter]); switch(spriteChoice[bulletCounter]) { case 0: { toSpawn->setTileIndex(g_bulletSpriteTilesPos); break; } case 1: { toSpawn->setTileIndex(g_missileSpriteTilesPos); break; } default: { assert2(false, "The sprite choice was outside the cases given."); break; } } if(player.getPoweredUpFire()) toSpawn->setPalette(1); else toSpawn->setPalette(0); toSpawn->setVisible(true); bulletCounter++; } } else { EnemyBulletIterator bullets = enemyBullets.alloc(count); int bulletCounter = 0; Bullet * toSpawn; while ((toSpawn = bullets.next()) != 0) { toSpawn->setPos(x[bulletCounter], y[bulletCounter]); toSpawn->setPath(paths[bulletCounter]); toSpawn->setDamage(damage[bulletCounter]); toSpawn->setTileIndex(g_bulletSpriteTilesPos); toSpawn->setPalette(8); toSpawn->setVisible(true); bulletCounter++; } } }
static void find_or_alloc_leaf( extbmp_t *ebmp, word untagged_w, leaf_t **leaf_recv, word *first_addr_for_leaf ) { bool retval_ignored = find_leaf_calc_offset( ebmp, untagged_w, leaf_recv, first_addr_for_leaf, TRUE ); assert2(retval_ignored); }
void msgc_unmark_object( msgc_context_t *context, word obj ) { word bit_idx, word_idx; assert2( context->lowest_heap_address <= ptrof( obj ) && ptrof( obj ) < context->highest_heap_address ); my_unmark_object( context, obj ); }
/* NOTE: A copy of this code exists in Sparc/memory.s; if you change * anything here, check that code as well. */ int stk_restore_frame( word *globals ) { word *stktop, *hframe, *p; word retoffs, proc, codeaddr, codeptr, header; unsigned size; assert2(globals[ G_STKP ] == globals[ G_STKBOT ]); hframe = ptrof( globals[ G_CONT ] ); size = roundup8( sizefield( *hframe ) + 4 ); /* bytes to copy */ stktop = (word*)globals[ G_STKP ]; stktop -= size / 4; if (stktop < (word*)globals[ G_ETOP ]) { supremely_annoyingmsg( "Failed to create stack." ); return 0; } globals[ G_STKP ] = (word)stktop; globals[ G_STKUFLOW ] += 1; #if 0 annoyingmsg("Restore: %d", size); #endif /* copy the frame onto the stack */ p = stktop; while (size) { *p++ = *hframe++; *p++ = *hframe++; size -= 8; } /* Follow continuation chain. */ globals[ G_CONT ] = *(stktop+STK_DYNLINK); header = *(stktop+HC_HEADER); retoffs = *(stktop+HC_RETOFFSET); proc = *(stktop+HC_PROC); /* convert the header back to a fixnum */ *(stktop+STK_CONTSIZE) = sizefield(header); /* convert the return address */ if (proc != 0) { codeptr = *(ptrof( proc )+PROC_CODEPTR); if (tagof( codeptr ) == BVEC_TAG) { codeaddr = (word)ptrof( codeptr ); *(stktop+STK_RETADDR) = (codeaddr+4)+retoffs; } else { *(stktop+STK_RETADDR) = retoffs; } } else { *(stktop+STK_RETADDR) = retoffs; } return 1; }
static void assert2_root_address_mapped( msgc_context_t *context, word *loc ) { #ifndef NDEBUG2 if (isptr(*loc) && ! gc_is_address_mapped( context->gc, ptrof(*loc), FALSE )) { assert2(0); } #endif }
void GraphicsSystem::unregisterPostRenderCallback(uint64_t callback_id) { const auto itr = std::find_if(std::begin(_post_render_callbacks), std::end(_post_render_callbacks), [callback_id](const Callback& callback) {return callback.id == callback_id; }); assert2(itr != std::end(_post_render_callbacks), "No post render callback with ID %" PRIu64 " exists.", callback_id); _post_render_callbacks.erase(itr); }
void msgc_mark_object( msgc_context_t *context, word obj ) { word bit_idx, word_idx; assert2( context->lowest_heap_address <= ptrof( obj ) && ptrof( obj ) < context->highest_heap_address ); bit_idx = (obj - (word)context->lowest_heap_address) >> BIT_IDX_SHIFT; word_idx = bit_idx >> BITS_TO_WORDS; context->bitmap[ word_idx ] |= 1 << (bit_idx & BIT_IN_WORD_MASK); }
/* Returns TRUE iff untagged_w was already in ebmp */ bool extbmp_add_elem( extbmp_t *ebmp, word untagged_w ) { /* ebmp := ebmp U { untagged_w } */ leaf_t *leaf; word first, lim; word entry_word; bool retval; unsigned int bit_idx, word_idx, bit_in_word; assert( tagof(untagged_w) == 0 ); first = 0xFFFFFFF; lim = 0x0; find_or_alloc_leaf( ebmp, untagged_w, &leaf, &first ); lim = leaf_wordaddr_lim( ebmp, first ); assert( first <= untagged_w ); assert( untagged_w < lim ); bit_idx = (untagged_w - first) >> BIT_IDX_SHIFT; word_idx = bit_idx >> BIT_IDX_TO_WORDADDR; bit_in_word = 1 << (bit_idx & BIT_IN_WORD_MASK); #if 0 if ( ! (bit_in_word & leaf->bitmap[ word_idx ] )) consolemsg(" extbmp_add_elem new elem: 0x%08x (%d) mhdr:0x%08x", untagged_w, gen_of(untagged_w), *(ptrof(untagged_w)) ); #endif entry_word = leaf->bitmap[ word_idx ]; retval = entry_word & bit_in_word; entry_word |= bit_in_word; leaf->bitmap[ word_idx ] = entry_word; assert2( extbmp_is_member(ebmp, untagged_w )); { int gno; gno = gen_of( untagged_w ); assert( gno != 0 ); if (leaf->gno == 0) { /* mixed leaf; do nothing */ } else if (leaf->gno < 0) { insert_leaf_in_list( ebmp, leaf, gno ); } else if (leaf->gno != gno) { move_leaf_to_mixed_list( ebmp, leaf, gno ); } } return retval; }
GraphicsSystem::GraphicsSystem(EntityManager *em, int window_width, int window_height) { _window = SDL_CreateWindow("Objectless", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, SDL_WINDOW_SHOWN); _renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); _entitymanager = em; // Initialize the flags for image lib if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { assert2(false, "IMG_Init failed!! %s", SDL_GetError()); exit(0); } }
int main() { int X = 0; bool B = false; assert(X == 1); assert(X = 1); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect [misc-assert-side-effect] my_assert(X = 1); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found my_assert() with side effect convoluted_assert(X = 1); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found convoluted_assert() with side effect not_my_assert(X = 1); assert(++X); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert(!B); assert(B || true); assert(freeFunction()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect MyClass mc; assert(mc.badFunc(0, 1)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert(mc.goodFunc(0, 1)); MyClass mc2; assert(mc2 = mc); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert(-mc > 0); MyClass *mcp; assert(mcp = new MyClass); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert((delete mcp, false)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert((throw 1, false)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() with side effect assert2(1 == 2 - 1); return 0; }
static void assert2_object_contents_mapped( msgc_context_t *context, word w, int n ) { #ifndef NDEBUG2 int i; for ( i=0 ; i < n ; i++ ) { if (isptr(vector_ref( w, i )) && ! gc_is_address_mapped( context->gc, ptrof(vector_ref( w, i )), FALSE )) { consolemsg("unmapped address, vector 0x%08x in gen %d, elem [%d] = 0x%08x", w, gen_of( w ), i, vector_ref( w, i )); consolemsg("(gno count: %d)", context->gc->gno_count); assert2(0); } } #endif }
static void assert2_los_addresses_mapped( msgc_context_t *context, word obj, int k, int next ) { #ifndef NDEBUG2 int i; for ( i=0 ; i < k ; i++ ) { if (isptr(vector_ref(obj, i+next)) && ! gc_is_address_mapped( context->gc, ptrof(vector_ref(obj, i+next)), FALSE )) { assert( gc_is_address_mapped( context->gc, ptrof(obj), TRUE )); consolemsg("unmapped address, los vector 0x%08x in gen %d, elem [%d] = 0x%08x", obj, gen_of(obj), i+next, vector_ref(obj, i+next )); consolemsg("(gno count: %d)", context->gc->gno_count); assert2(0); } } #endif }
int main(void) { volatile int failed = 1; /* safety in presence of longjmp() */ fclose (stderr); stderr = tmpfile (); if (!stderr) abort (); signal (SIGABRT, sigabrt); if (!setjmp (rec)) assert1 (); else failed = 0; /* should happen */ if (!setjmp (rec)) assert2 (); else failed = 1; /* should not happen */ if (!setjmp (rec)) assert3 (); else failed = 1; /* should not happen */ rewind (stderr); fgets (buf, 160, stderr); if (!strstr(buf, strerror (1))) failed = 1; fgets (buf, 160, stderr); if (strstr (buf, strerror (0))) failed = 1; fgets (buf, 160, stderr); if (strstr (buf, strerror (2))) failed = 1; return failed; }
int FsBitmap::allocateFreeExtent(uint32_t &ag, uint32_t required_size, std::vector<uint32_t> &blocks, uint32_t forbidden_ag) { ag = ag % this->AGCount(); // [0, AGCount()-1] uint32_t start_ag = ag; do { if (forbidden_ag == ag) { // avoid forbidden ag ag = (ag + 1) % this->AGCount(); // next continue; } ag_entry &fe = this->ag_free_extents[ag]; uint32_t k = 0; while (k < fe.size() && fe[k].len >= required_size) k ++; if (k > 0) { // there was least one appropriate extent: k --; // previous, use it assert1 (k < fe.size()); // k must point to some element in vector assert2 ("extent should be large enough", fe[k].len >= required_size); blocks.clear(); // fill blocks vector, decreasing extent while (required_size > 0) { blocks.push_back(fe[k].start); fe[k].start ++; fe[k].len --; required_size --; } // length must stay non-negative assert1 ((fe[k].len & 0x80000000) == 0); // catch overflow, as .len unsigned // if we used whole extent, its length is zero, and it should be removed if (0 == fe[k].len) { fe.list.erase(fe.list.begin() + k); } // sort by length std::sort (fe.list.begin(), fe.list.end(), compare_by_extent_length_obj); return RFSD_OK; } ag = (ag + 1) % this->AGCount(); // proceed with next, wrap is necessary } while (ag != start_ag); return RFSD_FAIL; }
void GraphicsSystem::step(float /*delta_time*/) { SDL_SetRenderDrawColor(_renderer, 0x00, 0x00, 0x5B, 0xFF); SDL_RenderClear(_renderer); for (unsigned int id : _entities) { Graphics *g = _entitymanager->get_component<Graphics>(id); if (!g->is_visible) { continue; } Transform *transform = _entitymanager->get_component<Transform>(id); /* create destination rect using the desired position * and the texture's dimensions */ SDL_Rect dest; dest.x = (int)transform->position.x; dest.y = (int)transform->position.y; dest.w = (int)(g->texture->getWidth() * transform->scale.x); dest.h = (int)(g->texture->getHeight() * transform->scale.y); const float radians_to_degrees = 57.324841f; const float rotation_degrees = transform->rotation.GetAngle() * radians_to_degrees; SDL_Point zero{ 0, 0 }; bool success = SDL_RenderCopyEx(_renderer, g->texture->getTexture(), nullptr, &dest, rotation_degrees, &zero, SDL_FLIP_NONE) == 0; assert2(success, "Failed to render texture '%s'. SDL error: %s", g->texture->getName().c_str(), SDL_GetError()); } for (auto& post_render_callback : _post_render_callbacks) { post_render_callback.function(); } SDL_RenderPresent(_renderer); }
static void assert2_basic_invs( msgc_context_t *context, word src, word obj ) { #ifndef NDEBUG2 word TMP = obj; if (isptr(TMP)) { gc_check_remset_invs( context->gc, src, obj ); assert2( (context)->lowest_heap_address <= ptrof(TMP) ); assert2( ptrof(TMP) < (context)->highest_heap_address ); if (! gc_is_address_mapped( context->gc, ptrof(TMP), FALSE )) { assert2(gc_is_address_mapped( context->gc, ptrof(TMP), TRUE )); } if (tagof(TMP) == PAIR_TAG) { /* no header on pairs... */ } else if (tagof(TMP) == VEC_TAG) { assert2(ishdr(*ptrof(TMP))); assert2(header(*ptrof(TMP)) == header(VEC_HDR)); } else if (tagof(TMP) == PROC_TAG) { assert2(ishdr(*ptrof(TMP))); assert2(header(*ptrof(TMP)) == header(PROC_HDR)); } } #endif }
int main(void) { assert2(); }
bool Polygon::Contains(const vec &worldSpacePoint, float polygonThicknessSq) const { // Implementation based on the description from http://erich.realtimerendering.com/ptinpoly/ if (p.size() < 3) return false; vec basisU = BasisU(); vec basisV = BasisV(); assert1(basisU.IsNormalized(), basisU); assert1(basisV.IsNormalized(), basisV); assert2(basisU.IsPerpendicular(basisV), basisU, basisV); assert3(basisU.IsPerpendicular(PlaneCCW().normal), basisU, PlaneCCW().normal, basisU.Dot(PlaneCCW().normal)); assert3(basisV.IsPerpendicular(PlaneCCW().normal), basisV, PlaneCCW().normal, basisV.Dot(PlaneCCW().normal)); vec normal = basisU.Cross(basisV); // float lenSq = normal.LengthSq(); ///\todo Could we treat basisU and basisV unnormalized here? float dot = normal.Dot(vec(p[0]) - worldSpacePoint); if (dot*dot > polygonThicknessSq) return false; int numIntersections = 0; const float epsilon = 1e-4f; // General strategy: transform all points on the polygon onto 2D face plane of the polygon, where the target query point is // centered to lie in the origin. // If the test ray (0,0) -> (+inf, 0) intersects exactly an odd number of polygon edge segments, then the query point must have been // inside the polygon. The test ray is chosen like that to avoid all extra per-edge computations. vec vt = vec(p.back()) - worldSpacePoint; float2 p0 = float2(Dot(vt, basisU), Dot(vt, basisV)); if (Abs(p0.y) < epsilon) p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly. for(int i = 0; i < (int)p.size(); ++i) { vt = vec(p[i]) - worldSpacePoint; float2 p1 = float2(Dot(vt, basisU), Dot(vt, basisV)); if (Abs(p1.y) < epsilon) p1.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly. if (p0.y * p1.y < 0.f) // If the line segment p0 -> p1 straddles the line x=0, it could intersect the ray (0,0) -> (+inf, 0) { if (Min(p0.x, p1.x) > 0.f) // If both x-coordinates are positive, then there certainly is an intersection with the ray. ++numIntersections; else if (Max(p0.x, p1.x) > 0.f) // If one of them is positive, there could be an intersection. (otherwise both are negative and they can't intersect ray) { // P = p0 + t*(p1-p0) == (x,0) // p0.x + t*(p1.x-p0.x) == x // p0.y + t*(p1.y-p0.y) == 0 // t == -p0.y / (p1.y - p0.y) // Test whether the lines (0,0) -> (+inf,0) and p0 -> p1 intersect at a positive X-coordinate? float2 d = p1 - p0; if (d.y != 0.f) { float t = -p0.y / d.y; // The line segment parameter, t \in [0,1] forms the line segment p0->p1. float x = p0.x + t * d.x; // The x-coordinate of intersection with the ray. if (t >= 0.f && t <= 1.f && x > 0.f) ++numIntersections; } } } p0 = p1; } return numIntersections % 2 == 1; }
void stk_flush( word *globals ) { word *stktop, *stkbot, *first, *prev; word retaddr, codeaddr, codeptr, proc, size; unsigned framecount; assert2( tagof( globals[ G_REG0 ]) == PROC_TAG ); stktop = (word*)globals[ G_STKP ]; stkbot = (word*)globals[ G_STKBOT ]; stack_state.words_flushed += (stkbot-stktop); first = prev = 0; framecount = 0; while (stktop < stkbot) { size = *(stktop+STK_CONTSIZE); retaddr = *(stktop+STK_RETADDR); /* convert header to vector header */ assert2( size % 4 == 0 ); /* size must be words, a fixnum */ assert2( (s_word)size >= 12 ); /* 3-word minimum, and nonnegative */ *(stktop+HC_HEADER) = mkheader( size, VEC_HDR ); /* convert return address */ proc = *(stktop+STK_REG0); if (proc != 0) { assert2( tagof( proc ) == PROC_TAG ); codeptr = *(ptrof( proc )+PROC_CODEPTR); if (tagof( codeptr ) == BVEC_TAG) { codeaddr = (word)ptrof( codeptr ); *(stktop+HC_RETOFFSET) = retaddr-(codeaddr+4); } else { *(stktop+HC_RETOFFSET) = retaddr; } } else { *(stktop+HC_RETOFFSET) = retaddr; } /* chain things together */ if (first == 0) first = stktop; else *(prev+HC_DYNLINK) = (word)tagptr( stktop, VEC_TAG ); prev = stktop; framecount++; size = roundup8( size+4 ); stktop += size / 4; #if 0 annoyingmsg("Flush: %d", size ); #endif } if (prev != 0) *(prev+HC_DYNLINK) = globals[ G_CONT ]; if (first != 0) globals[ G_CONT ] = (word)tagptr( first, VEC_TAG ); globals[ G_STKBOT ] = globals[ G_STKP ]; stack_state.frames_flushed += framecount; }
void assert2(bool condition) { assert2(condition, ""); }