-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata.c
128 lines (118 loc) · 3.11 KB
/
data.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
void color_table(int c, int w, int h)
{
int p;
printf("\nd_color_table_%x:", c);
for (p = 0; p < w * h / 2; p += 2) {
if (p % 24 == 0) printf("\ndw ");
printf("0x%04x,", c + (c << 4) + (c << 8) + (c << 12));
}
}
typedef enum {
MAP_LINE = 1,
MAP_DISK,
} map_prim;
typedef struct {
map_prim type;
int x0; // line, disk
int y0; // line, disk
int x1; // line
int y1; // line
double radius; // disk
} map_prim_data;
static const map_prim_data g_map[] = {
// Lines delimiting map square
{ MAP_LINE, 1, 1, 15, 1, 0.0 },
{ MAP_LINE, 15, 1, 15, 15, 0.0 },
{ MAP_LINE, 15, 15, 1, 15, 0.0 },
{ MAP_LINE, 1, 15, 1, 1, 0.0 },
{ MAP_LINE, 1, 4, 10, 4, 0.0 },
{ MAP_LINE, 10, 4, 10, 3, 0.0 },
{ MAP_LINE, 10, 1, 10, 2, 0.0 },
{ MAP_LINE, 3, 10, 15, 10, 0.0 },
{ MAP_LINE, 3, 10, 15, 10, 0.0 },
{ MAP_LINE, 3, 10, 3, 11, 0.0 },
{ MAP_LINE, 3, 15, 3, 13, 0.0 },
{ MAP_LINE, 12, 10, 12, 12, 0.0 },
{ MAP_LINE, 12, 15, 12, 14, 0.0 },
{ MAP_LINE, 92, 10, 12, 12, 0.0 },
{ MAP_LINE, 12, 15, 12, 14, 0.0 },
// Line from (2,8) to (8,2)
// Disk at (12,12) radius (1.5)
//{ MAP_DISK, 12, 12, 0, 0, 1.5 },
};
void map_trace_line(uint8_t *m, int w, int h, int x0, int y0, int x1, int y1)
{
int dx = abs(x1 - x0);
int sx = x0 < x1 ? 1 : -1;
int dy = -abs(y1 - y0);
int sy = y0 < y1 ? 1 : -1;
int err = dx + dy;
int x = x0, y = y0;
while (1) {
int err2 = 2*err;
m[y * w + x] = 1;
if (x == x1 && y == y1)
break;
if (err2 >= dy) {
err += dy;
x += sx;
}
if (err2 <= dx) {
err += dx;
y += sy;
}
}
}
void map_trace_disk(uint8_t *m, int w, int h, int x0, int y0, double radius)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
if ((x - x0)*(x - x0) + (y - y0)*(y - y0) < radius*radius) {
m[w * y + x] = 1;
}
}
}
}
void map(int w, int h, int q)
{
int p;
int wb = w << q;
int hb = h << q;
size_t num_prims = sizeof(g_map) / sizeof(g_map[0]);
uint8_t *m = calloc(wb * hb, 1);
uint8_t *mp;
int poffs;
for (p = 0; p < num_prims; p++) {
map_prim_data d = g_map[p];
if (d.type == MAP_LINE) {
map_trace_line(m, wb, hb, d.x0 << q, d.y0 << q, d.x1 << q, d.y1 << q);
} else if (d.type == MAP_DISK) {
map_trace_disk(m, wb, hb, d.x0 << q, d.y0 << q, d.radius * pow(2, q));
}
}
// Print an ASCII preview in comments
for (mp = m, poffs = 0; poffs < wb*hb; mp += 2, poffs += 2) {
if (poffs % 128 == 0) printf("\n; ");
printf("%c%c", *mp ? 35 : ' ', *(mp + 1) ? 35 : ' ');
}
printf("\nd_map:");
for (mp = m, poffs = 0; poffs < wb*hb; mp += 2, poffs += 2) {
if (poffs % 24 == 0) printf("\ndw ");
printf("0x%04x,", *mp + (*(mp + 1) << 8));
}
free(m);
}
int main(int argc, char **argv)
{
int i;
for (i = 0; i < 16; i++) {
color_table(i, 4, 240);
}
map(16, 16, 3);
return 0;
}