8 * Another World graphics convertor
9 * Only DOS version are supported
12 #define MAX_POLYGONS 4096
13 #define MAX_GROUPS 2048
14 #define MSG_USAGE "usage: spr INPUT\n"
15 #define MSG_OPENERR "can't open file %s.\n"
16 #define MSG_WRITEERR "can't create file %s.\n"
20 uint8_t color
, w
, h
, num
;
41 uint16_t datalen
, datapc
;
43 struct polygoninfo poly
[MAX_POLYGONS
];
45 struct groupinfo group
[MAX_GROUPS
];
49 return data
[datapc
++];
53 return (vbyte() << 8) | vbyte();
56 int findpoly(uint16_t offset
) {
57 for(int i
= 0; i
< polycount
; i
++) {
58 if(poly
[i
].offset
== offset
)
65 int findgroup(uint16_t offset
) {
66 for(int i
= 0; i
< groupcount
; i
++) {
67 if(group
[i
].offset
== offset
)
74 void process(bool readgroup
) {
75 uint16_t adr
= datapc
;
76 uint8_t type
= vbyte();
79 uint8_t color
= (type
& 0x80) ? (type
& 0x3F) : 0x0;
82 uint8_t num
= vbyte();
85 poly
[polycount
].offset
= adr
;
86 poly
[polycount
].color
= color
;
87 poly
[polycount
].w
= w
;
88 poly
[polycount
].h
= h
;
89 poly
[polycount
].num
= num
;
92 for(int i
= 0; i
< num
; i
++) {
97 poly
[polycount
].point
[i
].x
= x
;
98 poly
[polycount
].point
[i
].y
= y
;
109 uint8_t childs
= vbyte();
112 group
[groupcount
].offset
= adr
;
113 group
[groupcount
].x
= x
;
114 group
[groupcount
].y
= y
;
115 group
[groupcount
].num
= childs
;
118 for(int i
= 0; i
<= childs
; i
++) {
119 uint16_t offset
= vword();
120 uint8_t xx
= vbyte();
121 uint8_t yy
= vbyte();
122 uint16_t color
= 0xF;
125 color
= vword() & 0x7F;
127 offset
= (offset
& 0x7FFF) << 1;
130 group
[groupcount
].child
[i
].offset
= offset
;
131 group
[groupcount
].child
[i
].x
= xx
;
132 group
[groupcount
].child
[i
].y
= yy
;
133 group
[groupcount
].child
[i
].color
= color
;
140 printf("invalid type %u\n", type
);
147 for(int i
= 0; i
< groupcount
; i
++) {
148 for(int j
= 0; j
< group
[i
].num
; i
++) {
149 uint16_t offset
= group
[i
].child
[j
].offset
;
151 group
[i
].child
[j
].group
= false;
152 int id
= findpoly(offset
);
154 group
[i
].child
[j
].group
= true;
155 id
= findgroup(offset
);
157 printf("grouped polygon 0x%X not found\n", offset
);
162 group
[i
].child
[j
].id
= id
;
167 uint8_t *loadfile(const char *name
, uint16_t *size
) {
169 if((fp
= fopen(name
, "r")) == NULL
) {
170 printf(MSG_OPENERR
, name
);
174 fseek(fp
, 0, SEEK_END
);
176 fseek(fp
, 0, SEEK_SET
);
178 uint8_t *ptr
= malloc(s
);
179 fread(ptr
, s
, 1, fp
);
186 void svg_poly(char *prefix
, int id
) {
188 snprintf(name
, 256, "%s_p%i.svg", prefix
, id
);
189 if((fp
= fopen(name
, "w")) == NULL
) {
190 printf(MSG_WRITEERR
, name
);
202 printf("1px is p%i\n", id
);
204 fprintf(fp
, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n");
205 fprintf(fp
, "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"%upx\" height=\"%upx\">\n", w
, h
);
207 fprintf(fp
, "<polygon fill=\"black\" points=\"");
208 if(poly
[id
].num
== 1) {
209 fprintf(fp
, "%u,%u ", poly
[id
].point
[0].x
, poly
[id
].point
[0].y
);
210 } else if(poly
[id
].num
== 2) {
213 if (poly
[id
].point
[j
].x
> poly
[id
].point
[i
].x
) {
214 fprintf(fp
, "%u,%u ", poly
[id
].point
[i
].x
, poly
[id
].point
[i
].y
);
215 fprintf(fp
, "%u,%u ", poly
[id
].point
[j
].x
+ 1, poly
[id
].point
[j
].y
);
217 fprintf(fp
, "%u,%u ", poly
[id
].point
[j
].x
, poly
[id
].point
[j
].y
);
218 fprintf(fp
, "%u,%u ", poly
[id
].point
[i
].x
+ 1, poly
[id
].point
[i
].y
);
221 for(int i
= 0; i
< poly
[id
].num
/ 2; i
++) {
222 int j
= poly
[id
].num
- 1 - i
;
223 if (poly
[id
].point
[j
].x
> poly
[id
].point
[i
].x
) {
224 fprintf(fp
, "%u,%u ", poly
[id
].point
[i
].x
, poly
[id
].point
[i
].y
);
225 fprintf(fp
, "%u,%u ", poly
[id
].point
[j
].x
+ 1, poly
[id
].point
[j
].y
);
227 fprintf(fp
, "%u,%u ", poly
[id
].point
[j
].x
, poly
[id
].point
[j
].y
);
228 fprintf(fp
, "%u,%u ", poly
[id
].point
[i
].x
+ 1, poly
[id
].point
[i
].y
);
232 fprintf(fp
, "\"/>\n");
234 fprintf(fp
, "</svg>");
239 void svg_group(char *prefix
, int id
) {
241 snprintf(name
, 256, "%s_g%i.svg", prefix
, id
);
242 if((fp
= fopen(name
, "w")) == NULL
) {
243 printf(MSG_WRITEERR
, name
);
247 fprintf(fp
, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n");
248 fprintf(fp
, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" width=\"320px\" height=\"200px\">\n");
250 for(int i
= 0; i
< group
[id
].num
; i
++) {
251 char c
= group
[id
].child
[i
].group
? 'g' : 'p';
253 fprintf(fp
, "<image xlink:href=\"%s_%c%i.svg\" x=\"%i\" y=\"%i\"/>", prefix
, c
, group
[id
].child
[i
].id
, group
[id
].child
[i
].x
, group
[id
].child
[i
].y
);
256 fprintf(fp
, "</svg>");
261 int main(int argc
, char **argv
) {
267 data
= loadfile(argv
[1], &datalen
);
269 while(datapc
< datalen
)
273 while(datapc
< datalen
)
280 for(int i
= 0; i
< polycount
; i
++)
281 svg_poly(argv
[1], i
);
283 for(int i
= 0; i
< groupcount
; i
++)
284 svg_group(argv
[1], i
);