mirror of https://github.com/dirtbags/tanks.git
Start at a javascript tank designer
This commit is contained in:
parent
ac4e3b5157
commit
39169bf352
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Tank Designer</title>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background-color: #444444;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
#preview {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#sensors input {
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
#program textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 20em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="application/javascript" src="tanks.js"></script>
|
||||||
|
<script type="application/javascript" src="designer.js"></script>
|
||||||
|
<script type="application/javascript">
|
||||||
|
window.onload = design;
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="preview"><canvas id="design"></canvas><p id="debug"></p></div>
|
||||||
|
<form>
|
||||||
|
<fieldset id="metadata">
|
||||||
|
<legend>Information</legend>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Tank name:</td>
|
||||||
|
<td><input name="name"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Author:</td>
|
||||||
|
<td><input name="author"> (eg. Joe Cool
|
||||||
|
<joe@cool.cc>)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Color:</td>
|
||||||
|
<td><input name="color" type="color" value="#c0c0c0"
|
||||||
|
onchange="update();"> (eg. #c7e148)</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset id="sensors">
|
||||||
|
<legend>Sensors</legend>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>#</td>
|
||||||
|
<td>Range</td>
|
||||||
|
<td>Angle</td>
|
||||||
|
<td>Width</td>
|
||||||
|
<td>Turret?</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>0</td>
|
||||||
|
<td><input name="s0r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s0a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s0w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s0t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>1</td>
|
||||||
|
<td><input name="s1r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s1a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s1w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s1t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>2</td>
|
||||||
|
<td><input name="s2r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s2a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s2w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s2t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>3</td>
|
||||||
|
<td><input name="s3r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s3a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s3w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s3t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>4</td>
|
||||||
|
<td><input name="s4r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s4a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s4w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s4t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>5</td>
|
||||||
|
<td><input name="s5r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s5a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s5w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s5t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>6</td>
|
||||||
|
<td><input name="s6r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s6a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s6w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s6t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>7</td>
|
||||||
|
<td><input name="s7r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s7a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s7w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s7t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>8</td>
|
||||||
|
<td><input name="s8r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s8a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s8w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s8t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>9</td>
|
||||||
|
<td><input name="s9r" type="number" min="0" max="100" onchange="update();"></td>
|
||||||
|
<td><input name="s9a" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s9w" type="number" min="0" max="360" onchange="update();"></td>
|
||||||
|
<td><input name="s9t" type="checkbox" onchange="update();"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset id="program">
|
||||||
|
<legend>Program</legend>
|
||||||
|
<textarea name="program"></textarea>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue