13 int csprite(struct image *img, int x, int y, int xsz, int ysz);
14 int proc_sheet(const char *fname);
15 void print_usage(const char *argv0);
17 int tile_xsz, tile_ysz;
22 const char *name = "sprite";
24 int main(int argc, char **argv)
29 for(i=1; i<argc; i++) {
30 if(argv[i][0] == '-') {
31 if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "-size") == 0) {
32 if(sscanf(argv[++i], "%dx%d", &tile_xsz, &tile_ysz) != 2 ||
33 tile_xsz <= 0 || tile_ysz <= 0) {
34 fprintf(stderr, "%s must be followed by WIDTHxHEIGHT\n", argv[i - 1]);
38 } else if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "-rect") == 0) {
40 if(sscanf(argv[++i], "%dx%d+%d+%d", &rect.w, &rect.h, &rect.x, &rect.y) < 2 || rect.w <= 0 || rect.h <= 0) {
41 fprintf(stderr, "%s must be followed by WIDTHxHEIGHT+X+Y\n", argv[i - 1]);
45 } else if(strcmp(argv[i], "-coffset") == 0) {
46 cmap_offs = strtol(argv[++i], &endp, 10);
47 if(endp == argv[i] || cmap_offs < 0 || cmap_offs >= 256) {
48 fprintf(stderr, "-coffset must be followed by a valid colormap offset\n");
52 } else if(strcmp(argv[i], "-fbpitch") == 0) {
53 fbpitch = atoi(argv[++i]);
55 fprintf(stderr, "-fbpitch must be followed by a positive number\n");
59 } else if(strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "-name") == 0) {
62 fprintf(stderr, "%s must be followed by a name\n", argv[i - 1]);
66 } else if(strcmp(argv[i], "-k") == 0 || strcmp(argv[i], "-key") == 0) {
67 ckey = strtol(argv[++i], &endp, 10);
68 if(endp == argv[i] || ckey < 0 || ckey >= 256) {
69 fprintf(stderr, "%s must be followed by a valid color key\n", argv[i - 1]);
73 } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
78 fprintf(stderr, "invalid option: %s\n", argv[i]);
84 if(proc_sheet(argv[i]) == -1) {
93 const char *prefixfmt =
96 "\tmov eax, [esp + 12]\n"
99 "\tadd eax, [esp + 8]\n"
100 "\tadd eax, [esp + 4]\n"
102 "\tmov eax, [esp + 16]\n"
103 "\tjmp [.tiletab + eax * 4]\n\n"
106 int proc_sheet(const char *fname)
108 int i, j, num_xtiles, num_ytiles, xsz, ysz, tidx;
111 if(load_image(&img, fname) == -1) {
112 fprintf(stderr, "failed to load image: %s\n", fname);
121 num_xtiles = num_ytiles = 1;
125 num_xtiles = rect.w / tile_xsz;
126 num_ytiles = rect.h / tile_ysz;
131 printf(prefixfmt, name, name, fbpitch);
132 for(i=0; i<num_ytiles*num_xtiles; i++) {
133 printf("\tdd .tile%d\n", i);
138 for(i=0; i<num_ytiles; i++) {
139 for(j=0; j<num_xtiles; j++) {
140 printf(".tile%d:\n", tidx++);
141 csprite(&img, rect.x + j * xsz, rect.y + i * ysz, xsz, ysz);
145 /* output colormap */
146 printf("\n\tglobal %s_cmap_size\n", name);
147 printf("\tglobal %s_cmap\n", name);
148 printf("%s_cmap_size: dd %d\n\n", name, img.cmap_ncolors);
149 printf("%s_cmap:\n", name);
151 for(i=0; i<img.cmap_ncolors; i++) {
152 printf("\tdb %d, %d, %d\n", img.cmap[i].r, img.cmap[i].g, img.cmap[i].b);
166 unsigned char op, val;
170 int csprite(struct image *img, int x, int y, int xsz, int ysz)
172 int i, j, numops, mode, new_mode, start, skip_acc;
173 unsigned char *pptr = img->pixels + y * img->scansz + x;
174 struct csop *ops, *optr;
176 ops = optr = alloca((xsz + 1) * ysz * sizeof *ops);
178 for(i=0; i<ysz; i++) {
183 optr++->op = CSOP_ENDL;
186 for(j=0; j<xsz; j++) {
188 new_mode = CSOP_SKIP;
190 new_mode = CSOP_COPY;
193 if(new_mode != mode) {
197 optr->len = j - start;
205 pptr += img->scansz - xsz;
210 optr->len = xsz - start;
216 pptr = img->pixels + y * img->scansz + x;
219 /* edx points to dest */
220 for(i=0; i<numops; i++) {
223 skip_acc += optr->len;
228 skip_acc += fbpitch - xsz;
229 pptr += img->scansz - xsz;
234 printf("\tadd edx, %d\n", skip_acc);
238 for(j=0; j<optr->len / 4; j++) {
239 printf("\tmov dword [edx + %d], 0x%x\n", j * 4, *(uint32_t*)pptr);
243 switch(optr->len % 4) {
245 printf("\tmov byte [edx + %d], 0x%x\n", j++, (unsigned int)*pptr++);
247 printf("\tmov word [edx + %d], 0x%x\n", j, (unsigned int)*(uint16_t*)pptr);
252 printf("\tmov byte [edx + %d], 0x%x\n", j++, (unsigned int)*pptr++);
256 skip_acc = optr->len;
260 printf("\t; invalid op: %d\n", optr->op);
269 void print_usage(const char *argv0)
271 printf("Usage: %s [options] <spritesheet>\n", argv0);
272 printf("Options:\n");
273 printf(" -s,-size <WxH>: tile size (default: whole image)\n");
274 printf(" -r,-rect <WxH+X+Y>: use rectangle of the input image (default: whole image)\n");
275 printf(" -coffset <offs>: colormap offset [0, 255] (default: 0)\n");
276 printf(" -fbpitch <pitch>: target framebuffer pitch (scanline size in bytes)\n");
277 printf(" -k,-key <color>: color-key for transparency (default: 0)\n");
278 printf(" -h: print usage and exit\n");