diff --git a/designer.cgi.c b/designer.cgi.c new file mode 100644 index 0000000..17ae09d --- /dev/null +++ b/designer.cgi.c @@ -0,0 +1,128 @@ +#include +#include +#include + +struct string { + char *s; + size_t size; + size_t len; +}; + +void +string_append(struct string *str, char c) +{ + if (str->len < str->size) { + str->s[str->len++] = c; + } +} + +int +string_cmp(struct string *a, char *b, size_t blen) +{ + if (a->len > blen) { + return 1; + } else if (a->len < blen) { + return -1; + } else { + return memcmp(a->s, b, blen); + } +} + +void +string_cpy(struct string *dst, struct string *src) +{ + if (dst->size < src->len) { + dst->len = dst->size; + } else { + dst->len = src->len; + } + memcpy(dst->s, src->s, dst->len); +} + +char +tonum(int c) +{ + if ((c >= '0') && (c <= '9')) { + return c - '0'; + } + if ((c >= 'a') && (c <= 'f')) { + return 10 + c - 'a'; + } + if ((c >= 'A') && (c <= 'F')) { + return 10 + c - 'A'; + } + return 0; +} + +char +read_hex(FILE *f) +{ + int a = fgetc(f); + int b = fgetc(f); + + return tonum(a)*16 + tonum(b); +} + +/* Read a key or a value. Since & and = aren't supposed to appear + outside of boundaries, we can use the same function for both. +*/ +int +read_item(FILE *f, struct string *str) +{ + int c; + + while (1) { + c = fgetc(f); + switch (c) { + case EOF: + return 0; + break; + case '=': + case '&': + return 1; + break; + case '%': + string_append(str, read_hex(f)); + break; + default: + string_append(str, c); + break; + } + } +} + +int +read_pair(FILE *f, struct string *key, struct string *val) +{ + if (! read_item(f, key)) { + return 0; + } + return read_item(f, val); +} + +#define new_string(name, size) \ + char _##name[size]; \ + struct string name = {_##name, size, 0 } + +int +main(int argc, char *argv[]) +{ + int sensor[10][4]; + + new_string(key, 20); + new_string(val, 8192); + new_string(name, 20); + new_string(author, 20); + + printf("Content-type: text/plain\n\n"); + + while (! feof(stdin)) { + read_pair(stdin, &key, &val); + write(1, key.s, key.len); + write(1, "=", 1); + write(1, val.s, val.len); + write(1, "\n", 1); + } + + return 0; +} diff --git a/designer.html b/designer.html new file mode 100644 index 0000000..d0d9151 --- /dev/null +++ b/designer.html @@ -0,0 +1,145 @@ + + + + Tank Designer + + + + + + +

+
+
+ Information + + + + + + + + + + + + + +
Tank name:
Author: (eg. Joe Cool + <joe@cool.cc>)
Color: (eg. #c7e148)
+
+ +
+ Sensors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#RangeAngleWidthTurret?
0
1
2
3
4
5
6
7
8
9
+
+ +
+ Program + +
+ + +
+ + diff --git a/designer.js b/designer.js new file mode 100644 index 0000000..0c3889a --- /dev/null +++ b/designer.js @@ -0,0 +1,59 @@ +var canvas; +var ctx; +var tank; + +function min(a, b) { + if (a < b) { + return a; + } else { + return b; + } +} + +function deg2rad(angle) { + return angle*Math.PI/180; +} + +function update() { + var color = document.getElementsByName('color')[0].value; + var sensors = new Array(); + + for (i = 0; i < 4; i += 1) { + var range = document.getElementsByName('s'+i+'r')[0].value; + var angle = document.getElementsByName('s'+i+'a')[0].value; + var width = document.getElementsByName('s'+i+'w')[0].value; + var turret = document.getElementsByName('s'+i+'t')[0].checked; + + sensors[i] = [min(range, 100), + deg2rad(angle % 360), + deg2rad(width % 360), + turret]; + } + + tank = new Tank(ctx, 200, 200, color, sensors); +} + +function design() { + var frame = 0; + var loop_id; + + canvas = document.getElementById('design'); + ctx = canvas.getContext('2d'); + + canvas.width = 200; + canvas.height = 200; + + tank = new Tank(ctx, 200, 200, "#c0c0c0", []); + + function update() { + var turret = frame * Math.PI / 90; + + frame += 1; + canvas.width = canvas.width; + tank.set_state(100, 100, Math.PI * 1.5, turret, 0, 0); + tank.draw_tank(); + tank.draw_sensors(); + } + + loop_id = setInterval(update, 66); +}