-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMapdata.c
145 lines (122 loc) · 3.56 KB
/
Mapdata.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
Interpret the compressed vector map database
*/
#include "sunclock.h"
/* Codes in the map data bytestream:
Byte 1 Arguments Meaning
========== ========= ============
00 mv1 mv2 - Two short draw commands
01 dxx dyy - One longer draw command
10 mv1 000 - One short draw command
11 000 000 - Long move command
ax ax ay ay
11 000 001 - Long draw command
ax ax ay ay
11 000 010 - Medium draw command
dx dy
11 000 011 - Medium move command
dx dy
*/
/* MAPDRAW -- Decode map data, scale, and output vectors. You call
this function with:
mapdraw(<X_pixels>, <Y_pixels>, <vectorproc>);
Where X_pixels and Y_pixels specify the size of the
desired image area, and vectorproc is a function that
receives the individual vectors of the map. The
image is scaled to look best when X_pixels is twice
Y_pixels, but you're free to use any aspect ratio you
like. The vectorproc function should be declared
like this sample:
void vectorproc(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
printf("Draw from %d,%d to %d,%d.\n:,
x1, y1, x2, y2);
}
The pixel at the upper left of the image is 0,0, and
addresses increase to the right and downward. A
sample call on mapdraw would then be:
mapdraw(512, 256, vectorproc);
*/
void mapdraw(int xsize, int ysize,
void (PASCAL *vector)(int x1, int y1, int x2, int y2))
{
int x1 = -32700, y1 = -32700, x2, y2;
unsigned char far *maptr;
unsigned char far *mapend;
unsigned int l;
HANDLE hRes;
hRes = LoadResource(hInst,
FindResource(hInst, "MapData", "MAPVECTORS"));
maptr = LockResource(hRes);
l = (maptr[0] << 8) | maptr[1];
maptr += 2;
mapend = maptr + l;
while (maptr < mapend) {
static int xdec[] = {-1, 0, 1, -1, 1, -1, 0, 1};
static int ydec[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int b = *maptr++;
#define unfit(x, n) ((x) - ((1 << (n)) / 2));
#define pxy(x,y) ((int)(((x)*(long)xsize)/2048L)),((int)(((y)*(long)ysize)/1024L))
switch (b >> 6) {
int d;
case 0:
d = (b >> 3) & 7;
x2 = x1 + xdec[d];
y2 = y1 + ydec[d];
vector(pxy(x1, y1), pxy(x2, y2));
x1 = x2;
y1 = y2;
d = b & 7;
x2 = x1 + xdec[d];
y2 = y1 + ydec[d];
vector(pxy(x1, y1), pxy(x2, y2));
break;
case 1:
x2 = x1 + unfit((b >> 3) & 7, 3);
y2 = y1 + unfit(b & 7, 3);
vector(pxy(x1, y1), pxy(x2, y2));
break;
case 2:
d = (b >> 3) & 7;
x2 = x1 + xdec[d];
y2 = y1 + ydec[d];
vector(pxy(x1, y1), pxy(x2, y2));
break;
case 3:
switch (b & 077) {
case 0: /* Long move */
x2 = *maptr++;
x2 = (x2 << 8) | *maptr++;
y2 = *maptr++;
y2 = (y2 << 8) | *maptr++;
break;
case 1: /* Long draw */
x2 = *maptr++;
x2 = (x2 << 8) | *maptr++;
y2 = *maptr++;
y2 = (y2 << 8) | *maptr++;
vector(pxy(x1, y1), pxy(x2, y2));
break;
case 2: /* Medium draw */
x2 = *maptr++;
x2 = x1 + unfit(x2, 8);
y2 = *maptr++;
y2 = y1 + unfit(y2, 8);
vector(pxy(x1, y1), pxy(x2, y2));
break;
case 3: /* Medium move */
x2 = *maptr++;
x2 = x1 + unfit(x2, 8);
y2 = *maptr++;
y2 = y1 + unfit(y2, 8);
break;
}
break;
}
x1 = x2;
y1 = y2;
}
UnlockResource(hRes);
FreeResource(hRes);
}