void phree(void* pointer) { // Free da pointah unsigned char* ptr = (unsigned char*)pointer; int num_slices = -1; #ifdef DEBUG_MEM printf("phree(ptr: %d)\n", ptr); #endif // Get slice count (Stored in 4 bytes preceeding the pointer) num_slices = (*(ptr - 4) << 24) | (*(ptr - 3) << 16) | (*(ptr - 2) << 8) | *(ptr - 1); assert3(num_slices > 0 && num_slices < MAX_ALLOCATED_SLICES, "phree(0x%h): Invalid arg, slice count: %d\n", ptr, num_slices); ptr -= 4; // Make sure we deallocate the size bytes as well // ptr now points to the address, figure out the offset to find the slice start number unsigned int start_slice = (ptr - gMemory) / BYTES_PER_SLICE; assert3(start_slice >= 0 && start_slice < MAX_ALLOCATED_SLICES - 2, "phree(0x%h): Invalid arg, slice start: %d\n", ptr, start_slice); //assert_uart(start_slice < 0 || start_slice > MAX_ALLOCATED_SLICES - 2, "Invalid ptr passed to phree()"); mark_slices(start_slice, num_slices, false); gBytesAllocated -= num_slices * 4; #ifdef DEBUG_MEM // Should use Uart_SendString here instead, but it currently doesn't take va_arg //printf("Freed %d bytes, %d allocated.\n", num_slices * 4, gBytesAllocated); #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; }
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; }