Example #1
0
int		consume_room(char *line, struct s_lem_in *lemin, int *state)
{
	static struct s_room **forward_alloc;
	char	**split;

	split = ft_strsplit(line, ' ');
	if (!ft_strcmp("##start", line))
		forward_alloc = &lemin->start;
	else if (!ft_strcmp("##end", line))
		forward_alloc = &lemin->end;
	else if (forward_alloc != 0 && arraylen(split) == 3)
	{
		*forward_alloc = alloc_room(ft_strdup(split[0]));
		lemin_push_room(lemin, *forward_alloc);
		forward_alloc = 0;
	}
	else if (arraylen(split) == 3)
		lemin_push_room(lemin, alloc_room(ft_strdup(split[0])));
	else
	{
		*state = TUBE;
		consume_tube(line, lemin, state);
	}
	free_array(split);
	return (0);
}
Example #2
0
void TestFibonacciRecursive(CuTest *tc) {
  int expected[] = {0, 1, 1, 2, 3, 5};
  int actual[arraylen(expected)];
  int len = arraylen(expected);
  for (int i = 0; i < len; i++) {
    actual[i] = fibonacciRecursive(i);
  }
  CuAssertStrEquals(tc,
                    IntArrayToString(expected, len),
                    IntArrayToString(actual, len));
}
Example #3
0
void TestFibonacciExponent(CuTest *tc) {
  int tests[] = {0,1,2,3,4,5,10,40,45};
  int expected[arraylen(tests)];
  int actual[arraylen(expected)];
  int len = arraylen(tests);
  for (int i = 0; i < len; i++) {
    int num = tests[i];
    expected[i] = fibonacciClosedForm(num);
    actual[i] = fibonacciExponent(num);
  }
  CuAssertStrEquals(tc,
                    IntArrayToString(expected, len),
                    IntArrayToString(actual, len));
}
Example #4
0
void TestFibonacciIterative(CuTest *tc) {
  int tests[] = {0,1,2,3,4,5,10,12};
  int expected[arraylen(tests)];
  int actual[arraylen(expected)];
  int len = arraylen(tests);
  for (int i = 0; i < len; i++) {
    int num = tests[i];
    expected[i] = fibonacciRecursive(num);
    actual[i] = fibonacciIterative(num);
  }
  CuAssertStrEquals(tc,
                    IntArrayToString(expected, len),
                    IntArrayToString(actual, len));
}
Example #5
0
static void post_implications(post_t *post, alloc_func_t alloc,
                              alloc_data_t *adata, post_taglist_t **res)
{
	impl_iterator_data_t impldata;
	post_taglist_t *tl;
	assert(post);
	assert(alloc);
	impldata.list = NULL;
	impldata.len = 0;
	impldata.weak = T_NO;
	impldata.callback = impl_cb;
again:
	tl = impldata.weak ? post->weak_tags : &post->tags;
	while (tl) {
		for (int i = 0; i < arraylen(tl->tags); i++) {
			tag_t *tag = tl->tags[i];
			if (tag && tag->implications) {
				impldata.tag = tag;
				impldata.tagvalue = tl->values[i];
				impllist_iterate(tag->implications, &impldata);
			}
		}
		tl = tl->next;
	}
	if (!impldata.weak) {
		impldata.weak = T_YES;
		goto again;
	}
	if (!impldata.list && impldata.len) {
		impldata.list = malloc(sizeof(*impldata.list) * impldata.len);
		impldata.len = 0;
		impldata.weak = T_NO;
		goto again;
	}
	if (impldata.list) {
		implcomp_data_t *list = impldata.list;
		int             len = impldata.len;
		sort(list, len, sizeof(*list), impl_comp, NULL);
		for (int i = 0; i < len; i++) {
			int skip = 0;
			for (int j = 0; j < i; j++) {
				if (list[i].impl->tag == list[j].impl->tag) {
					skip = 1;
					break;
				}
			}
			if (!skip && list[i].impl->positive) {
				tag_value_t *value = list[i].impl->set_value;
				if (list[i].impl->inherit_value) {
					value = list[i].i_value;
				}
				taglist_add(&res[list[i].weak],
				            list[i].impl->tag, value,
				            alloc, adata);
			}
		}
		free(list);
	}
}
Example #6
0
int taglist_contains(const post_taglist_t *tl, const tag_t *tag)
{
	while (tl) {
		for (int i = 0; i < arraylen(tl->tags); i++) {
			if (tl->tags[i] == tag) return 1;
		}
		tl = tl->next;
	}
	return 0;
}
Example #7
0
static void impllist_iterate(impllist_t *impl, impl_iterator_data_t *data)
{
	while (impl) {
		for (int i = 0; i < arraylen(impl->impl); i++) {
			if (impl->impl[i].tag) {
				data->callback(&impl->impl[i], data);
			}
		}
		impl = impl->next;
	}
}
Example #8
0
HMENU CreateGraphicsWindowMenus(void)
{
    HMENU top = CreateMenu();
    HMENU m = 0;

    int i;
    int subMenu = 0;

    for(i = 0; SS.GW.menu[i].level >= 0; i++) {
        char label[100] = { '\0' };
        if(SS.GW.menu[i].label) {
            char accelbuf[40];
            const char *sep =
                MakeAcceleratorLabel(SS.GW.menu[i].accel, accelbuf) ?
                "\t" : "";
            sprintf(label, "%s%s%s", SS.GW.menu[i].label, sep, accelbuf);
        }

        if(SS.GW.menu[i].level == 0) {
            m = CreateMenu();
            AppendMenu(top, MF_STRING | MF_POPUP, (UINT_PTR)m, label);
            if(subMenu >= (int)arraylen(SubMenus)) oops();
            SubMenus[subMenu] = m;
            subMenu++;
        } else if(SS.GW.menu[i].level == 1) {
            if(SS.GW.menu[i].id == GraphicsWindow::MNU_OPEN_RECENT) {
                RecentOpenMenu = CreateMenu();
                AppendMenu(m, MF_STRING | MF_POPUP,
                    (UINT_PTR)RecentOpenMenu, label);
            } else if(SS.GW.menu[i].id == GraphicsWindow::MNU_GROUP_RECENT) {
                RecentImportMenu = CreateMenu();
                AppendMenu(m, MF_STRING | MF_POPUP,
                    (UINT_PTR)RecentImportMenu, label);
            } else if(SS.GW.menu[i].label) {
                AppendMenu(m, MF_STRING, SS.GW.menu[i].id, label);
            } else {
                AppendMenu(m, MF_SEPARATOR, SS.GW.menu[i].id, "");
            }
        } else oops();
    }
    RefreshRecentMenus();

    return top;
}
// This code is correct
void TestValid(CuTest* tc) {
  int actual[] = {
    luhn("4111111111111111"),
    luhn("5500000000000004"),
    luhn("30000000000004"),
    luhn("4111111112111111"),
    luhn("4123103910123940"),
  };
  int expected[] = {
    true,
    true,
    true,
    false,
    false,
  };
  int len = arraylen(actual);
  CuAssertStrEquals(tc,
                    BoolArrayToString(expected, len),
                    BoolArrayToString(actual, len)
                   );
}
Example #10
0
// Mostly the same thing as post_tag()
static int post_tag_set_value(post_t *post, const tag_t *tag, truth_t weak,
                              tag_value_t *value)
{
	assert(post);
	assert(tag);
	post_taglist_t *tl = (weak ? post->weak_tags : &post->tags);
	while (tl) {
		unsigned int i;
		for (i = 0; i < arraylen(tl->tags); i++) {
			if (tl->tags[i] == tag) {
				if (tl->values[i] == value) {
					return 0;
				} else {
					tl->values[i] = value;
					return 1;
				}
			}
		}
		tl = tl->next;
	}
	return 0;
}
Example #11
0
static int taglist_add(post_taglist_t **tlp, tag_t *tag, tag_value_t *value,
                       alloc_func_t alloc, alloc_data_t *adata)
{
	post_taglist_t *tl = *tlp;
	while (tl) {
		for (int i = 0; i < arraylen(tl->tags); i++) {
			if (!tl->tags[i]) {
				tl->tags[i] = tag;
				tl->values[i] = value;
				return 0;
			}
			if (tl->tags[i] == tag) return 1;
		}
		tl = tl->next;
	}
	tl = alloc(adata, sizeof(*tl));
	tl->tags[0] = tag;
	tl->values[0] = value;
	tl->next = *tlp;
	*tlp = tl;
	return 0;
}
Example #12
0
int		consume_tube(char *line, struct s_lem_in *lemin, int *state)
{
	struct s_room	*s1;
	struct s_room	*s2;
	char			**split;

	(void)state;
	(void)lemin;
	split = ft_strsplit(line, '-');
	if (arraylen(split) == 2)
	{
		s1 = get_room(lemin, split[0]);
		s2 = get_room(lemin, split[1]);

		if (s1 && s2 && ft_strcmp(split[0], split[1]))
		{
			room_push_room(s1, s2);
			room_push_room(s2, s1);
		}
	}
	free_array(split);
	return (0);
}
Example #13
0
HMENU CreateGraphicsWindowMenus(void)
{
    HMENU top = CreateMenu();
    HMENU m;

    int i;
    int subMenu = 0;
    
    for(i = 0; SS.GW.menu[i].level >= 0; i++) {
        if(SS.GW.menu[i].level == 0) {
            m = CreateMenu();
            AppendMenu(top, MF_STRING | MF_POPUP, (UINT_PTR)m, 
                                                        SS.GW.menu[i].label);

            if(subMenu >= arraylen(SubMenus)) oops();
            SubMenus[subMenu] = m;
            subMenu++;
        } else if(SS.GW.menu[i].level == 1) {
            if(SS.GW.menu[i].label) {
                AppendMenu(m, MF_STRING, SS.GW.menu[i].id, SS.GW.menu[i].label);
            } else {
                AppendMenu(m, MF_SEPARATOR, SS.GW.menu[i].id, "");
            }
        } else if(SS.GW.menu[i].level == 10) {
            RecentOpenMenu = CreateMenu();
            AppendMenu(m, MF_STRING | MF_POPUP,
                (UINT_PTR)RecentOpenMenu, SS.GW.menu[i].label);
        } else if(SS.GW.menu[i].level == 11) {
            RecentImportMenu = CreateMenu();
            AppendMenu(m, MF_STRING | MF_POPUP,
                (UINT_PTR)RecentImportMenu, SS.GW.menu[i].label);
        } else oops();
    }
    RefreshRecentMenus();

    return top;
}
Example #14
0
static void MenuById(int id, bool yes, bool check)
{
    int i;
    int subMenu = -1;

    for(i = 0; SS.GW.menu[i].level >= 0; i++) {
        if(SS.GW.menu[i].level == 0) subMenu++;

        if(SS.GW.menu[i].id == id) {
            if(subMenu < 0) oops();
            if(subMenu >= (int)arraylen(SubMenus)) oops();

            if(check) {
                CheckMenuItem(SubMenus[subMenu], id,
                            yes ? MF_CHECKED : MF_UNCHECKED);
            } else {
                EnableMenuItem(SubMenus[subMenu], id,
                            yes ? MF_ENABLED : MF_GRAYED);
            }
            return;
        }
    }
    oops();
}
Example #15
0
void GraphicsWindow::MouseLeftDown(double mx, double my) {
    orig.mouseDown = true;

    if(GraphicsEditControlIsVisible()) {
        orig.mouse = Point2d::From(mx, my);
        orig.mouseOnButtonDown = orig.mouse;
        HideGraphicsEditControl();
        return;
    }
    SS.TW.HideEditControl();

    if(SS.showToolbar) {
        if(ToolbarMouseDown((int)mx, (int)my)) return;
    }

    // Make sure the hover is up to date.
    MouseMoved(mx, my, false, false, false, false, false);
    orig.mouse.x = mx;
    orig.mouse.y = my;
    orig.mouseOnButtonDown = orig.mouse;

    // The current mouse location
    Vector v = offset.ScaledBy(-1);
    v = v.Plus(projRight.ScaledBy(mx/scale));
    v = v.Plus(projUp.ScaledBy(my/scale));

    hRequest hr;
    switch(pending.operation) {
        case MNU_DATUM_POINT:
            hr = AddRequest(Request::DATUM_POINT);
            SK.GetEntity(hr.entity(0))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(0));

            ClearSuper();
            break;

        case MNU_LINE_SEGMENT:
            hr = AddRequest(Request::LINE_SEGMENT);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_LINE_POINT;
            pending.point = hr.entity(2);
            pending.description = "click next point of line, or press Esc";
            SK.GetEntity(pending.point)->PointForceTo(v);
            break;

        case MNU_RECTANGLE: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw rectangle in 3d; select a workplane first.");
                ClearSuper();
                break;
            }
            hRequest lns[4];
            int i;
            SS.UndoRemember();
            for(i = 0; i < 4; i++) {
                lns[i] = AddRequest(Request::LINE_SEGMENT, false);
            }
            for(i = 0; i < 4; i++) {
                Constraint::ConstrainCoincident(
                    lns[i].entity(1), lns[(i+1)%4].entity(2));
                SK.GetEntity(lns[i].entity(1))->PointForceTo(v);
                SK.GetEntity(lns[i].entity(2))->PointForceTo(v);
            }
            for(i = 0; i < 4; i++) {
                Constraint::Constrain(
                    (i % 2) ? Constraint::HORIZONTAL : Constraint::VERTICAL,
                    Entity::NO_ENTITY, Entity::NO_ENTITY,
                    lns[i].entity(0));
            }
            ConstrainPointByHovered(lns[2].entity(1));

            pending.operation = DRAGGING_NEW_POINT;
            pending.point = lns[1].entity(2);
            pending.description = "click to place other corner of rectangle";
            break;
        }
        case MNU_CIRCLE:
            hr = AddRequest(Request::CIRCLE);
            // Centered where we clicked
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            // Normal to the screen
            SK.GetEntity(hr.entity(32))->NormalForceTo(
                Quaternion::From(SS.GW.projRight, SS.GW.projUp));
            // Initial radius zero
            SK.GetEntity(hr.entity(64))->DistanceForceTo(0);

            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_RADIUS;
            pending.circle = hr.entity(0);
            pending.description = "click to set radius";
            break;

        case MNU_ARC: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw arc in 3d; select a workplane first.");
                ClearPending();
                break;
            }
            hr = AddRequest(Request::ARC_OF_CIRCLE);
            // This fudge factor stops us from immediately failing to solve
            // because of the arc's implicit (equal radius) tangent.
            Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale);
            SK.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj));
            SK.GetEntity(hr.entity(2))->PointForceTo(v);
            SK.GetEntity(hr.entity(3))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(2));

            ClearSuper();

            pending.operation = DRAGGING_NEW_ARC_POINT;
            pending.point = hr.entity(3);
            pending.description = "click to place point";
            break;
        }
        case MNU_CUBIC:
            hr = AddRequest(Request::CUBIC);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(2))->PointForceTo(v);
            SK.GetEntity(hr.entity(3))->PointForceTo(v);
            SK.GetEntity(hr.entity(4))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_CUBIC_POINT;
            pending.point = hr.entity(4);
            pending.description = "click next point of cubic, or press Esc";
            break;

        case MNU_WORKPLANE:
            if(LockedInWorkplane()) {
                Error("Sketching in a workplane already; sketch in 3d before "
                      "creating new workplane.");
                ClearSuper();
                break;
            }
            hr = AddRequest(Request::WORKPLANE);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(32))->NormalForceTo(
                Quaternion::From(SS.GW.projRight, SS.GW.projUp));
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();
            break;

        case MNU_TTF_TEXT: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw text in 3d; select a workplane first.");
                ClearSuper();
                break;
            }
            hr = AddRequest(Request::TTF_TEXT);
            Request *r = SK.GetRequest(hr);
            r->str.strcpy("Abc");
            r->font.strcpy("arial.ttf");

            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(2))->PointForceTo(v);

            pending.operation = DRAGGING_NEW_POINT;
            pending.point = hr.entity(2);
            pending.description = "click to place bottom left of text";
            break;
        }

        case MNU_COMMENT: {
            ClearSuper();
            Constraint c;
            ZERO(&c);
            c.group       = SS.GW.activeGroup;
            c.workplane   = SS.GW.ActiveWorkplane();
            c.type        = Constraint::COMMENT;
            c.disp.offset = v;
            c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
            Constraint::AddConstraint(&c);
            break;
        }

        case DRAGGING_RADIUS:
        case DRAGGING_NEW_POINT:
            // The MouseMoved event has already dragged it as desired.
            ClearPending();
            break;

        case DRAGGING_NEW_ARC_POINT:
            ConstrainPointByHovered(pending.point);
            ClearPending();
            break;

        case DRAGGING_NEW_CUBIC_POINT: {
            hRequest hr = pending.point.request();
            Request *r = SK.GetRequest(hr);

            if(hover.entity.v == hr.entity(1).v && r->extraPoints >= 2) {
                // They want the endpoints coincident, which means a periodic
                // spline instead.
                r->type = Request::CUBIC_PERIODIC;
                // Remove the off-curve control points, which are no longer
                // needed here; so move [2,ep+1] down, skipping first pt.
                int i;
                for(i = 2; i <= r->extraPoints+1; i++) {
                    SK.GetEntity(hr.entity((i-1)+1))->PointForceTo(
                        SK.GetEntity(hr.entity(i+1))->PointGetNum());
                }
                // and move ep+3 down by two, skipping both
                SK.GetEntity(hr.entity((r->extraPoints+1)+1))->PointForceTo(
                  SK.GetEntity(hr.entity((r->extraPoints+3)+1))->PointGetNum());
                r->extraPoints -= 2;
                // And we're done.
                SS.MarkGroupDirty(r->group);
                SS.ScheduleGenerateAll();
                ClearPending();
                break;
            }

            if(ConstrainPointByHovered(pending.point)) {
                ClearPending();
                break;
            }

            Entity e;
            if(r->extraPoints >= (int)arraylen(e.point) - 4) {
                ClearPending();
                break;
            }

            (SK.GetRequest(hr)->extraPoints)++;
            SS.GenerateAll(-1, -1);

            int ep = r->extraPoints;
            Vector last = SK.GetEntity(hr.entity(3+ep))->PointGetNum();

            SK.GetEntity(hr.entity(2+ep))->PointForceTo(last);
            SK.GetEntity(hr.entity(3+ep))->PointForceTo(v);
            SK.GetEntity(hr.entity(4+ep))->PointForceTo(v);
            pending.point = hr.entity(4+ep);
            break;
        }

        case DRAGGING_NEW_LINE_POINT: {
            if(hover.entity.v) {
                Entity *e = SK.GetEntity(hover.entity);
                if(e->IsPoint()) {
                    hRequest hrl = pending.point.request();
                    Entity *sp = SK.GetEntity(hrl.entity(1));
                    if(( e->PointGetNum()).Equals(
                       (sp->PointGetNum())))
                    {
                        // If we constrained by the hovered point, then we
                        // would create a zero-length line segment. That's
                        // not good, so just stop drawing.
                        ClearPending();
                        break;
                    }
                }
            }

            if(ConstrainPointByHovered(pending.point)) {
                ClearPending();
                break;
            }

            // Create a new line segment, so that we continue drawing.
            hRequest hr = AddRequest(Request::LINE_SEGMENT);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            // Displace the second point of the new line segment slightly,
            // to avoid creating zero-length edge warnings.
            SK.GetEntity(hr.entity(2))->PointForceTo(
                v.Plus(projRight.ScaledBy(0.5/scale)));

            // Constrain the line segments to share an endpoint
            Constraint::ConstrainCoincident(pending.point, hr.entity(1));

            // And drag an endpoint of the new line segment
            pending.operation = DRAGGING_NEW_LINE_POINT;
            pending.point = hr.entity(2);
            pending.description = "click next point of line, or press Esc";

            break;
        }

        case 0:
        default:
            ClearPending();
            if(!hover.IsEmpty()) {
                hoverWasSelectedOnMousedown = IsSelected(&hover);
                MakeSelected(&hover);
            }
            break;
    }

    SS.ScheduleShowTW();
    InvalidateGraphics();
}
Example #16
0
int CmdVchDemod(const char *Cmd)
{
  // Is this the entire sync pattern, or does this also include some
  // data bits that happen to be the same everywhere? That would be
  // lovely to know.
  static const int SyncPattern[] = {
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  };

  // So first, we correlate for the sync pattern, and mark that.
  int bestCorrel = 0, bestPos = 0;
  int i;
  // It does us no good to find the sync pattern, with fewer than
  // 2048 samples after it...
  for (i = 0; i < (GraphTraceLen-2048); i++) {
    int sum = 0;
    int j;
    for (j = 0; j < arraylen(SyncPattern); j++) {
      sum += GraphBuffer[i+j]*SyncPattern[j];
    }
    if (sum > bestCorrel) {
      bestCorrel = sum;
      bestPos = i;
    }
  }
  PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel);

  char bits[257];
  bits[256] = '\0';

  int worst = INT_MAX;
  int worstPos = 0;

  for (i = 0; i < 2048; i += 8) {
    int sum = 0;
    int j;
    for (j = 0; j < 8; j++) {
      sum += GraphBuffer[bestPos+i+j];
    }
    if (sum < 0) {
      bits[i/8] = '.';
    } else {
      bits[i/8] = '1';
    }
    if(abs(sum) < worst) {
      worst = abs(sum);
      worstPos = i;
    }
  }
  PrintAndLog("bits:");
  PrintAndLog("%s", bits);
  PrintAndLog("worst metric: %d at pos %d", worst, worstPos);

  if (strcmp(Cmd, "clone")==0) {
    GraphTraceLen = 0;
    char *s;
    for(s = bits; *s; s++) {
      int j;
      for(j = 0; j < 16; j++) {
        GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0;
      }
    }
    RepaintGraphWindow();
  }
  return 0;
}
Example #17
0
// Mode 3
int CmdHF15Demod(const char *Cmd)
{
	// The sampling rate is 106.353 ksps/s, for T = 18.8 us
	
	int i, j;
	int max = 0, maxPos = 0;

	int skip = 4;

	if (GraphTraceLen < 1000) return 0;

	// First, correlate for SOF
	for (i = 0; i < 100; i++) {
		int corr = 0;
		for (j = 0; j < arraylen(FrameSOF); j += skip) {
			corr += FrameSOF[j] * GraphBuffer[i + (j / skip)];
		}
		if (corr > max) {
			max = corr;
			maxPos = i;
		}
	}
	PrintAndLog("SOF at %d, correlation %d", maxPos,
		max / (arraylen(FrameSOF) / skip));
	
	i = maxPos + arraylen(FrameSOF) / skip;
	int k = 0;
	uint8_t outBuf[20];
	memset(outBuf, 0, sizeof(outBuf));
	uint8_t mask = 0x01;
	for (;;) {
		int corr0 = 0, corr1 = 0, corrEOF = 0;
		for (j = 0; j < arraylen(Logic0); j += skip) {
			corr0 += Logic0[j] * GraphBuffer[i + (j / skip)];
		}
		for (j = 0; j < arraylen(Logic1); j += skip) {
			corr1 += Logic1[j] * GraphBuffer[i + (j / skip)];
		}
		for (j = 0; j < arraylen(FrameEOF); j += skip) {
			corrEOF += FrameEOF[j] * GraphBuffer[i + (j / skip)];
		}
		// Even things out by the length of the target waveform.
		corr0 *= 4;
		corr1 *= 4;
		
		if (corrEOF > corr1 && corrEOF > corr0) {
			PrintAndLog("EOF at %d", i);
			break;
		} else if (corr1 > corr0) {
			i += arraylen(Logic1) / skip;
			outBuf[k] |= mask;
		} else {
			i += arraylen(Logic0) / skip;
		}
		mask <<= 1;
		if (mask == 0) {
			k++;
			mask = 0x01;
		}
		if ((i + (int)arraylen(FrameEOF)) >= GraphTraceLen) {
			PrintAndLog("ran off end!");
			break;
		}
	}
	if (mask != 0x01) {
		PrintAndLog("error, uneven octet! (discard extra bits!)");
		PrintAndLog("   mask=%02x", mask);
	}
	PrintAndLog("%d octets", k);
	
	for (i = 0; i < k; i++) {
		PrintAndLog("# %2d: %02x ", i, outBuf[i]);
	}
	PrintAndLog("CRC=%04x", Iso15693Crc(outBuf, k - 2));
	return 0;
}
Example #18
0
void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
{
    if(!IsInit) {
        InitHeaps();
        IsInit = 1;
    }

    int i;
    for(i = 0; i < ssys->params; i++) {
        Slvs_Param *sp = &(ssys->param[i]);
        Param p;
        ZERO(&p);
        
        p.h.v = sp->h;
        p.val = sp->val;
        SK.param.Add(&p);
        if(sp->group == shg) {
            SYS.param.Add(&p);
        }
    }

    for(i = 0; i < ssys->entities; i++) {
        Slvs_Entity *se = &(ssys->entity[i]);
        EntityBase e;
        ZERO(&e);

        switch(se->type) {
case SLVS_E_POINT_IN_3D:        e.type = Entity::POINT_IN_3D; break;
case SLVS_E_POINT_IN_2D:        e.type = Entity::POINT_IN_2D; break;
case SLVS_E_NORMAL_IN_3D:       e.type = Entity::NORMAL_IN_3D; break;
case SLVS_E_NORMAL_IN_2D:       e.type = Entity::NORMAL_IN_2D; break;
case SLVS_E_DISTANCE:           e.type = Entity::DISTANCE; break;
case SLVS_E_WORKPLANE:          e.type = Entity::WORKPLANE; break;
case SLVS_E_LINE_SEGMENT:       e.type = Entity::LINE_SEGMENT; break;
case SLVS_E_CUBIC:              e.type = Entity::CUBIC; break;
case SLVS_E_CIRCLE:             e.type = Entity::CIRCLE; break;
case SLVS_E_ARC_OF_CIRCLE:      e.type = Entity::ARC_OF_CIRCLE; break;

default: dbp("bad entity type %d", se->type); return;
        }
        e.h.v           = se->h;
        e.group.v       = se->group;
        e.workplane.v   = se->wrkpl;
        e.point[0].v    = se->point[0];
        e.point[1].v    = se->point[1];
        e.point[2].v    = se->point[2];
        e.point[3].v    = se->point[3];
        e.normal.v      = se->normal;
        e.distance.v    = se->distance;
        e.param[0].v    = se->param[0];
        e.param[1].v    = se->param[1];
        e.param[2].v    = se->param[2];
        e.param[3].v    = se->param[3];

        SK.entity.Add(&e);
    }

    for(i = 0; i < ssys->constraints; i++) {
        Slvs_Constraint *sc = &(ssys->constraint[i]);
        ConstraintBase c;
        ZERO(&c);

        int t;
        switch(sc->type) {
case SLVS_C_POINTS_COINCIDENT:  t = Constraint::POINTS_COINCIDENT; break;
case SLVS_C_PT_PT_DISTANCE:     t = Constraint::PT_PT_DISTANCE; break;
case SLVS_C_PT_PLANE_DISTANCE:  t = Constraint::PT_PLANE_DISTANCE; break;
case SLVS_C_PT_LINE_DISTANCE:   t = Constraint::PT_LINE_DISTANCE; break;
case SLVS_C_PT_FACE_DISTANCE:   t = Constraint::PT_FACE_DISTANCE; break;
case SLVS_C_PT_IN_PLANE:        t = Constraint::PT_IN_PLANE; break;
case SLVS_C_PT_ON_LINE:         t = Constraint::PT_ON_LINE; break;
case SLVS_C_PT_ON_FACE:         t = Constraint::PT_ON_FACE; break;
case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::EQUAL_LENGTH_LINES; break;
case SLVS_C_LENGTH_RATIO:       t = Constraint::LENGTH_RATIO; break;
case SLVS_C_EQ_LEN_PT_LINE_D:   t = Constraint::EQ_LEN_PT_LINE_D; break;
case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE:        t = Constraint::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_SYMMETRIC:          t = Constraint::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ:    t = Constraint::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT:     t = Constraint::SYMMETRIC_VERT; break;
case SLVS_C_SYMMETRIC_LINE:     t = Constraint::SYMMETRIC_LINE; break;
case SLVS_C_AT_MIDPOINT:        t = Constraint::AT_MIDPOINT; break;
case SLVS_C_HORIZONTAL:         t = Constraint::HORIZONTAL; break;
case SLVS_C_VERTICAL:           t = Constraint::VERTICAL; break;
case SLVS_C_DIAMETER:           t = Constraint::DIAMETER; break;
case SLVS_C_PT_ON_CIRCLE:       t = Constraint::PT_ON_CIRCLE; break;
case SLVS_C_SAME_ORIENTATION:   t = Constraint::SAME_ORIENTATION; break;
case SLVS_C_ANGLE:              t = Constraint::ANGLE; break;
case SLVS_C_PARALLEL:           t = Constraint::PARALLEL; break;
case SLVS_C_PERPENDICULAR:      t = Constraint::PERPENDICULAR; break;
case SLVS_C_ARC_LINE_TANGENT:   t = Constraint::ARC_LINE_TANGENT; break;
case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break;
case SLVS_C_EQUAL_RADIUS:       t = Constraint::EQUAL_RADIUS; break;
case SLVS_C_PROJ_PT_DISTANCE:   t = Constraint::PROJ_PT_DISTANCE; break;
case SLVS_C_WHERE_DRAGGED:      t = Constraint::WHERE_DRAGGED; break;
case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::CURVE_CURVE_TANGENT; break;

default: dbp("bad constraint type %d", sc->type); return;
        }

        c.type = t;

        c.h.v           = sc->h;
        c.group.v       = sc->group;
        c.workplane.v   = sc->wrkpl;
        c.valA          = sc->valA;
        c.ptA.v         = sc->ptA;
        c.ptB.v         = sc->ptB;
        c.entityA.v     = sc->entityA;
        c.entityB.v     = sc->entityB;
        c.entityC.v     = sc->entityC;
        c.entityD.v     = sc->entityD;
        c.other         = (sc->other) ? true : false;
        c.other2        = (sc->other2) ? true : false;

        SK.constraint.Add(&c);
    }

    for(i = 0; i < (int)arraylen(ssys->dragged); i++) {
        if(ssys->dragged[i]) {
            hParam hp = { ssys->dragged[i] };
            SYS.dragged.Add(&hp);
        }
    }

    Group g;
    ZERO(&g);
    g.h.v = shg;

    List<hConstraint> bad;
    ZERO(&bad);

    // Now we're finally ready to solve!
    bool andFindBad = ssys->calculateFaileds ? true : false;
    int how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false);

    switch(how) {
        case System::SOLVED_OKAY:
            ssys->result = SLVS_RESULT_OKAY;
            break;

        case System::DIDNT_CONVERGE:
            ssys->result = SLVS_RESULT_DIDNT_CONVERGE;
            break;

        case System::SINGULAR_JACOBIAN:
            ssys->result = SLVS_RESULT_INCONSISTENT;
            break;

        case System::TOO_MANY_UNKNOWNS:
            ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS;
            break;

        default: oops();
    }

    // Write the new parameter values back to our caller.
    for(i = 0; i < ssys->params; i++) {
        Slvs_Param *sp = &(ssys->param[i]);
        hParam hp = { sp->h };
        sp->val = SK.GetParam(hp)->val;
    }

    if(ssys->failed) {
        // Copy over any the list of problematic constraints.
        for(i = 0; i < ssys->faileds && i < bad.n; i++) {
            ssys->failed[i] = bad.elem[i].v;
        }
        ssys->faileds = bad.n;
    }

    bad.Clear();
    SYS.param.Clear();
    SYS.entity.Clear();
    SYS.eq.Clear();
    SYS.dragged.Clear();

    SK.param.Clear();
    SK.entity.Clear();
    SK.constraint.Clear();

    FreeAllTemporary();
}
Example #19
0
//-----------------------------------------------------------------------------
// Load a TrueType font into memory. We care about the curves that define
// the letter shapes, and about the mappings that determine which glyph goes
// with which character.
//-----------------------------------------------------------------------------
bool TtfFont::LoadFontFromFile(bool nameOnly) {
    if(loaded) return true;

    int i;
    
    fh = fopen(fontFile, "rb");
    if(!fh) {
        return false;
    }

    try {
        // First, load the Offset Table
        DWORD   version         = GetDWORD();
        WORD    numTables       = GetWORD();
        WORD    searchRange     = GetWORD();
        WORD    entrySelector   = GetWORD();
        WORD    rangeShift      = GetWORD();

        // Now load the Table Directory; our goal in doing this will be to
        // find the addresses of the tables that we will need.
        DWORD   glyfAddr = -1, glyfLen;
        DWORD   cmapAddr = -1, cmapLen;
        DWORD   headAddr = -1, headLen;
        DWORD   locaAddr = -1, locaLen;
        DWORD   maxpAddr = -1, maxpLen;
        DWORD   nameAddr = -1, nameLen;
        DWORD   hmtxAddr = -1, hmtxLen;
        DWORD   hheaAddr = -1, hheaLen;

        for(i = 0; i < numTables; i++) {
            char tag[5] = "xxxx";
            tag[0]              = GetBYTE();
            tag[1]              = GetBYTE();
            tag[2]              = GetBYTE();
            tag[3]              = GetBYTE();
            DWORD   checksum    = GetDWORD();
            DWORD   offset      = GetDWORD();
            DWORD   length      = GetDWORD();

            if(strcmp(tag, "glyf")==0) {
                glyfAddr = offset;
                glyfLen = length;
            } else if(strcmp(tag, "cmap")==0) {
                cmapAddr = offset;
                cmapLen = length;
            } else if(strcmp(tag, "head")==0) {
                headAddr = offset;
                headLen = length;
            } else if(strcmp(tag, "loca")==0) {
                locaAddr = offset;
                locaLen = length;
            } else if(strcmp(tag, "maxp")==0) {
                maxpAddr = offset;
                maxpLen = length;
            } else if(strcmp(tag, "name")==0) {
                nameAddr = offset;
                nameLen = length;
            } else if(strcmp(tag, "hhea")==0) {
                hheaAddr = offset;
                hheaLen = length;
            } else if(strcmp(tag, "hmtx")==0) {
                hmtxAddr = offset;
                hmtxLen = length;
            }
        }

        if(glyfAddr == -1 || cmapAddr == -1 || headAddr == -1 ||
           locaAddr == -1 || maxpAddr == -1 || hmtxAddr == -1 ||
           nameAddr == -1 || hheaAddr == -1)
        {
            throw "missing table addr";
        }

        // Load the name table. This gives us display names for the font, which
        // we need when we're giving the user a list to choose from.
        fseek(fh, nameAddr, SEEK_SET);

        WORD  nameFormat            = GetWORD();
        WORD  nameCount             = GetWORD();
        WORD  nameStringOffset      = GetWORD();
        // And now we're at the name records. Go through those till we find
        // one that we want.
        int displayNameOffset, displayNameLength;
        for(i = 0; i < nameCount; i++) {
            WORD    platformID      = GetWORD();
            WORD    encodingID      = GetWORD();
            WORD    languageID      = GetWORD();
            WORD    nameId          = GetWORD();
            WORD    length          = GetWORD();
            WORD    offset          = GetWORD();

            if(nameId == 4) {
                displayNameOffset = offset;
                displayNameLength = length;
                break;
            }
        }
        if(nameOnly && i >= nameCount) {
            throw "no name";
        }

        if(nameOnly) {
            // Find the display name, and store it in the provided buffer.
            fseek(fh, nameAddr+nameStringOffset+displayNameOffset, SEEK_SET);
            int c = 0;
            for(i = 0; i < displayNameLength; i++) {
                BYTE b = GetBYTE();
                if(b && c < (sizeof(name.str) - 2)) {
                    name.str[c++] = b;
                }
            }
            name.str[c++] = '\0';
         
            fclose(fh);
            return true;
        }


        // Load the head table; we need this to determine the format of the
        // loca table, 16- or 32-bit entries
        fseek(fh, headAddr, SEEK_SET);

        DWORD headVersion           = GetDWORD();
        DWORD headFontRevision      = GetDWORD();
        DWORD headCheckSumAdj       = GetDWORD();
        DWORD headMagicNumber       = GetDWORD();
        WORD  headFlags             = GetWORD();
        WORD  headUnitsPerEm        = GetWORD();
        (void)GetDWORD(); // created time
        (void)GetDWORD();
        (void)GetDWORD(); // modified time
        (void)GetDWORD();
        WORD  headXmin              = GetWORD();
        WORD  headYmin              = GetWORD();
        WORD  headXmax              = GetWORD();
        WORD  headYmax              = GetWORD();
        WORD  headMacStyle          = GetWORD();
        WORD  headLowestRecPPEM     = GetWORD();
        WORD  headFontDirectionHint = GetWORD();
        WORD  headIndexToLocFormat  = GetWORD();
        WORD  headGlyphDataFormat   = GetWORD();
        
        if(headMagicNumber != 0x5F0F3CF5) {
            throw "bad magic number";
        }

        // Load the hhea table, which contains the number of entries in the
        // horizontal metrics (hmtx) table.
        fseek(fh, hheaAddr, SEEK_SET);
        DWORD hheaVersion           = GetDWORD();
        WORD  hheaAscender          = GetWORD();
        WORD  hheaDescender         = GetWORD();
        WORD  hheaLineGap           = GetWORD();
        WORD  hheaAdvanceWidthMax   = GetWORD();
        WORD  hheaMinLsb            = GetWORD();
        WORD  hheaMinRsb            = GetWORD();
        WORD  hheaXMaxExtent        = GetWORD();
        WORD  hheaCaretSlopeRise    = GetWORD();
        WORD  hheaCaretSlopeRun     = GetWORD();
        WORD  hheaCaretOffset       = GetWORD();
        (void)GetWORD();
        (void)GetWORD();
        (void)GetWORD();
        (void)GetWORD();
        WORD  hheaMetricDataFormat  = GetWORD();
        WORD  hheaNumberOfMetrics   = GetWORD();

        // Load the maxp table, which determines (among other things) the number
        // of glyphs in the font
        fseek(fh, maxpAddr, SEEK_SET);

        DWORD maxpVersion               = GetDWORD();
        WORD  maxpNumGlyphs             = GetWORD();
        WORD  maxpMaxPoints             = GetWORD();
        WORD  maxpMaxContours           = GetWORD();
        WORD  maxpMaxComponentPoints    = GetWORD();
        WORD  maxpMaxComponentContours  = GetWORD();
        WORD  maxpMaxZones              = GetWORD();
        WORD  maxpMaxTwilightPoints     = GetWORD();
        WORD  maxpMaxStorage            = GetWORD();
        WORD  maxpMaxFunctionDefs       = GetWORD();
        WORD  maxpMaxInstructionDefs    = GetWORD();
        WORD  maxpMaxStackElements      = GetWORD();
        WORD  maxpMaxSizeOfInstructions = GetWORD();
        WORD  maxpMaxComponentElements  = GetWORD();
        WORD  maxpMaxComponentDepth     = GetWORD();

        glyphs = maxpNumGlyphs;
        glyph = (Glyph *)MemAlloc(glyphs*sizeof(glyph[0]));

        // Load the hmtx table, which gives the horizontal metrics (spacing
        // and advance width) of the font.
        fseek(fh, hmtxAddr, SEEK_SET);

        WORD  hmtxAdvanceWidth;
        SWORD hmtxLsb;
        for(i = 0; i < min(glyphs, hheaNumberOfMetrics); i++) {
            hmtxAdvanceWidth = GetWORD();
            hmtxLsb          = (SWORD)GetWORD();

            glyph[i].leftSideBearing = hmtxLsb;
            glyph[i].advanceWidth = hmtxAdvanceWidth;
        }
        // The last entry in the table applies to all subsequent glyphs also.
        for(; i < glyphs; i++) {
            glyph[i].leftSideBearing = hmtxLsb;
            glyph[i].advanceWidth = hmtxAdvanceWidth;
        }

        // Load the cmap table, which determines the mapping of characters to
        // glyphs.
        fseek(fh, cmapAddr, SEEK_SET);

        DWORD usedTableAddr = -1;

        WORD  cmapVersion        = GetWORD();
        WORD  cmapTableCount     = GetWORD();
        for(i = 0; i < cmapTableCount; i++) {
            WORD  platformId = GetWORD();
            WORD  encodingId = GetWORD();
            DWORD offset     = GetDWORD();

            if(platformId == 3 && encodingId == 1) {
                // The Windows Unicode mapping is our preference
                usedTableAddr = cmapAddr + offset;
            }
        }

        if(usedTableAddr == -1) {
            throw "no used table addr";
        }

        // So we can load the desired subtable; in this case, Windows Unicode,
        // which is us.
        fseek(fh, usedTableAddr, SEEK_SET);

        WORD  mapFormat             = GetWORD();
        WORD  mapLength             = GetWORD();
        WORD  mapVersion            = GetWORD();
        WORD  mapSegCountX2         = GetWORD();
        WORD  mapSearchRange        = GetWORD();
        WORD  mapEntrySelector      = GetWORD();
        WORD  mapRangeShift         = GetWORD();
        
        if(mapFormat != 4) {
            // Required to use format 4 per spec
            throw "not format 4";
        }

        int segCount = mapSegCountX2 / 2;
        WORD *endChar       = (WORD *)AllocTemporary(segCount*sizeof(WORD));
        WORD *startChar     = (WORD *)AllocTemporary(segCount*sizeof(WORD));
        WORD *idDelta       = (WORD *)AllocTemporary(segCount*sizeof(WORD));
        WORD *idRangeOffset = (WORD *)AllocTemporary(segCount*sizeof(WORD));

        DWORD *filePos = (DWORD *)AllocTemporary(segCount*sizeof(DWORD));

        for(i = 0; i < segCount; i++) {
            endChar[i] = GetWORD();
        }
        WORD  mapReservedPad        = GetWORD();
        for(i = 0; i < segCount; i++) {
            startChar[i] = GetWORD();
        }
        for(i = 0; i < segCount; i++) {
            idDelta[i] = GetWORD();
        }
        for(i = 0; i < segCount; i++) {
            filePos[i] = ftell(fh);
            idRangeOffset[i] = GetWORD();
        }

        // So first, null out the glyph table in our in-memory representation
        // of the font; any character for which cmap does not provide a glyph
        // corresponds to -1
        for(i = 0; i < arraylen(useGlyph); i++) {
            useGlyph[i] = 0;
        }

        for(i = 0; i < segCount; i++) {
            WORD v = idDelta[i];
            if(idRangeOffset[i] == 0) {
                int j;
                for(j = startChar[i]; j <= endChar[i]; j++) {
                    if(j > 0 && j < arraylen(useGlyph)) {
                        // Don't create a reference to a glyph that we won't
                        // store because it's bigger than the table.
                        if((WORD)(j + v) < glyphs) {
                            // Arithmetic is modulo 2^16
                            useGlyph[j] = (WORD)(j + v);
                        }
                    }
                }
            } else {
                int j;
                for(j = startChar[i]; j <= endChar[i]; j++) {
                    if(j > 0 && j < arraylen(useGlyph)) {
                        int fp = filePos[i];
                        fp += (j - startChar[i])*sizeof(WORD);
                        fp += idRangeOffset[i];
                        fseek(fh, fp, SEEK_SET);

                        useGlyph[j] = GetWORD();
                    }
                }
            }
        }

        // Load the loca table. This contains the offsets of each glyph,
        // relative to the beginning of the glyf table.
        fseek(fh, locaAddr, SEEK_SET);

        DWORD *glyphOffsets = (DWORD *)AllocTemporary(glyphs*sizeof(DWORD));

        for(i = 0; i < glyphs; i++) {
            if(headIndexToLocFormat == 1) {
                // long offsets, 32 bits
                glyphOffsets[i] = GetDWORD();
            } else if(headIndexToLocFormat == 0) {
                // short offsets, 16 bits but divided by 2
                glyphOffsets[i] = GetWORD()*2;
            } else {
                throw "bad headIndexToLocFormat";
            }
        }

        scale = 1024;
        // Load the glyf table. This contains the actual representations of the
        // letter forms, as piecewise linear or quadratic outlines.
        for(i = 0; i < glyphs; i++) {
            fseek(fh, glyfAddr + glyphOffsets[i], SEEK_SET);
            LoadGlyph(i);
        }
    } catch (char *s) {
        dbp("failed: '%s'", s);
        fclose(fh);
        return false;
    }

    fclose(fh);
    loaded = true;
    return true;
}