- pngdump tool overlay multiple images (combine spritesheets)
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 16 Mar 2021 09:00:13 +0000 (11:00 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 16 Mar 2021 09:00:13 +0000 (11:00 +0200)
- icons

Makefile
src/data.s
src/main.c
src/sprites.c
tools/pngdump/image.c
tools/pngdump/image.h
tools/pngdump/main.c

index 33bb3d8..be6de8f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,19 @@
 src = $(wildcard src/*.c)
 ssrc = $(wildcard src/*.s)
-#dataobj = data/data.o
 obj = $(src:.c=.o) $(ssrc:.s=.o) $(dataobj)
 dep = $(src:.c=.d)
 name = blender
 elf = $(name).elf
 bin = $(name).gba
 
+data = data/bg.raw data/bg.pal \
+          data/sprites.raw \
+          data/sprites1.pal \
+          data/sprites2.pal \
+          data/sprites3.pal \
+          data/sprites4.pal \
+          data/sprites5.pal
+
 ARCH = arm-none-eabi-
 
 CPP = $(ARCH)cpp
@@ -36,11 +43,14 @@ $(elf): $(obj)
 
 -include $(dep)
 
-src/data.o: src/data.s data/bg.raw data/bg.pal data/sprites.raw data/sprites.pal
+src/data.o: src/data.s $(data)
 
 tools/pngdump/pngdump:
        $(MAKE) -C tools/pngdump
 
+data/sprites.raw: data/sprites1.png data/sprites2.png data/sprites3.png data/sprites4.png data/sprites5.png
+       tools/pngdump/pngdump -o $@ -n $^
+
 %.raw: %.png tools/pngdump/pngdump
        tools/pngdump/pngdump -o $@ -n $<
 
index e6fc992..0cb4fc3 100644 (file)
@@ -19,4 +19,8 @@ sprites_pixels:
 
        .align 1
 sprites_cmap:
-       .incbin "data/sprites.pal"
+       .incbin "data/sprites1.pal"
+       .incbin "data/sprites2.pal"
+       .incbin "data/sprites3.pal"
+       .incbin "data/sprites4.pal"
+       .incbin "data/sprites5.pal"
index 7dc1a99..2110b9a 100644 (file)
@@ -35,10 +35,17 @@ enum {
        SIDX_ICONS_BASE
 };
 
+#define SNAM_START     512
 enum {
-       SNAM_DEL0       = 512,
-       SNAM_DEL1       = SNAM_DEL0 + 8,
-       SNAM_DEL2       = SNAM_DEL1 + 8
+       SNAM_DEL0               = SNAM_START,
+       SNAM_DEL1               = SNAM_DEL0 + 8,
+       SNAM_DEL2               = SNAM_DEL1 + 8,
+       SNAM_ICON_ZOOM  = SNAM_START + 24,
+       SNAM_ICON_PAN   = SNAM_ICON_ZOOM + 4,
+       SNAM_ICON_ORBIT = SNAM_START + 32 * 4 + 24,     /* for tiles down, 24 across */
+       SNAM_ICON_X             = SNAM_START + 32 * 8 + 26,
+       SNAM_ICON_Y             = SNAM_ICON_X + 2,
+       SNAM_ICON_Z             = SNAM_ICON_Y + 2
 };
 
 #define MENU_HEIGHT            17
@@ -120,6 +127,10 @@ int main(void)
        REG_BLDCNT = BLDCNT_ALPHA | BLDCNT_B_BG2;
        REG_BLDALPHA = 0x040c;
 
+       set_sprite(oam, SIDX_ICONS_BASE, SNAM_ICON_ZOOM, 213, 57, 4, SPR_SZ32);
+       set_sprite(oam, SIDX_ICONS_BASE + 1, SNAM_ICON_PAN, 213, 81, 4, SPR_SZ32);
+       set_sprite(oam, SIDX_ICONS_BASE + 2, SNAM_ICON_ORBIT, 213, 103, 4, SPR_SZ32);
+
        xgl_init();
        xgl_viewport(0, 0, 240, VP_HEIGHT);
        xgl_enable(XGL_LIGHTING);
index 91471d7..8cd5b2c 100644 (file)
@@ -32,7 +32,7 @@ void init_sprites(void)
        /* copy from cartridge to OBJ RAM */
        dst = (uint16_t*)VRAM_LFB_OBJ_ADDR;
        src = (uint16_t*)sprites_pixels;
-       for(i=0; i<256; i++) {  /* 256 tiles */
+       for(i=0; i<320; i++) {  /* 320 tiles */
                for(j=0; j<8; j++) {
                        *dst++ = src[j * 64];
                        *dst++ = src[j * 64 + 1];
@@ -46,9 +46,9 @@ void init_sprites(void)
        }
 
 
-       /* setup OBJ colormap 0 */
+       /* setup OBJ colormaps */
        cptr = (uint16_t*)CRAM_OBJ_ADDR;
-       for(i=0; i<16; i++) {
+       for(i=0; i<80; i++) {   /* 5 colormaps of 16 colors each */
                unsigned char r = sprites_cmap[i].r >> 3;
                unsigned char g = sprites_cmap[i].g >> 3;
                unsigned char b = sprites_cmap[i].b >> 3;
index 0ae86f9..f276e63 100644 (file)
@@ -235,3 +235,78 @@ void blit(struct image *src, int sx, int sy, int w, int h, struct image *dst, in
                sptr += src->pitch;
        }
 }
+
+static unsigned int get_pixel(struct image *img, int x, int y)
+{
+       unsigned char *pptr;
+       unsigned short *pptr16;
+
+       switch(img->bpp) {
+       case 4:
+               pptr = img->pixels + y * img->pitch + x / 2;
+               return x & 1 ? *pptr & 0xf : *pptr >> 4;
+       case 8:
+               pptr = img->pixels + y * img->pitch + x;
+               return *pptr;
+       case 16:
+               pptr16 = (unsigned short*)(img->pixels + y * img->pitch + x * 2);
+               return *pptr16;
+       default:
+               fprintf(stderr, "get_pixel not implemented for %d bpp\n", img->bpp);
+       }
+
+       return 0;
+}
+
+static void put_pixel(struct image *img, int x, int y, unsigned int pix)
+{
+       unsigned char *pptr;
+       unsigned short *pptr16;
+
+       switch(img->bpp) {
+       case 4:
+               pptr = img->pixels + y * img->pitch + x / 2;
+               if(x & 1) {
+                       *pptr = (*pptr & 0xf0) | pix;
+               } else {
+                       *pptr = (*pptr & 0xf) | (pix << 4);
+               }
+               break;
+
+       case 8:
+               pptr = img->pixels + y * img->pitch + x;
+               *pptr = pix;
+               break;
+
+       case 16:
+               pptr16 = (unsigned short*)(img->pixels + y * img->pitch + x * 2);
+               *pptr16 = pix;
+               break;
+
+       default:
+               fprintf(stderr, "put_pixel not implemented for %d bpp\n", img->bpp);
+       }
+}
+
+void overlay_key(struct image *src, unsigned int key, struct image *dst)
+{
+       int i, j;
+       unsigned char *sptr, *dptr;
+       unsigned int pix;
+
+       assert(src->bpp == dst->bpp);
+       assert(src->width == dst->width);
+       assert(src->height == dst->height);
+
+       sptr = src->pixels;
+       dptr = dst->pixels;
+
+       for(i=0; i<dst->height; i++) {
+               for(j=0; j<dst->width; j++) {
+                       pix = get_pixel(src, j, i);
+                       if(pix != key) {
+                               put_pixel(dst, j, i, pix);
+                       }
+               }
+       }
+}
index b9f24b4..7a42fba 100644 (file)
@@ -22,5 +22,6 @@ int save_image(struct image *img, const char *fname);
 int cmp_image(struct image *a, struct image *b);
 
 void blit(struct image *src, int sx, int sy, int w, int h, struct image *dst, int dx, int dy);
+void overlay_key(struct image *src, unsigned int key, struct image *dst);
 
 #endif /* IMAGE_H_ */
index a12fb3d..d7aba3e 100644 (file)
@@ -12,8 +12,10 @@ int main(int argc, char **argv)
        int i, mode = 0;
        int text = 0;
        int renibble = 0;
-       char *fname = 0, *outfname = 0;
-       struct image img;
+       char *outfname = 0;
+       char *infiles[256];
+       int num_infiles = 0;
+       struct image img, tmpimg;
        FILE *out = stdout;
 
        for(i=1; i<argc; i++) {
@@ -63,24 +65,38 @@ int main(int argc, char **argv)
                                return 1;
                        }
                } else {
-                       if(fname) {
-                               fprintf(stderr, "unexpected argument: %s\n", argv[i]);
-                               print_usage(argv[0]);
-                               return 1;
-                       }
-                       fname = argv[i];
+                       infiles[num_infiles++] = argv[i];
                }
        }
 
-       if(!fname) {
+       if(!num_infiles) {
                fprintf(stderr, "pass the filename of a PNG file\n");
                return 1;
        }
-       if(load_image(&img, fname) == -1) {
-               fprintf(stderr, "failed to load PNG file: %s\n", fname);
+       if(load_image(&img, infiles[0]) == -1) {
+               fprintf(stderr, "failed to load PNG file: %s\n", infiles[0]);
                return 1;
        }
 
+       for(i=1; i<num_infiles; i++) {
+               if(load_image(&tmpimg, infiles[i]) == -1) {
+                       fprintf(stderr, "failed to load PNG file: %s\n", infiles[i]);
+                       return 1;
+               }
+               if(tmpimg.width != img.width || tmpimg.height != img.height) {
+                       fprintf(stderr, "size mismatch: first image (%s) is %dx%d, %s is %dx%d\n",
+                                       infiles[0], img.width, img.height, infiles[i], tmpimg.width, tmpimg.height);
+                       return 1;
+               }
+               if(tmpimg.bpp != img.bpp) {
+                       fprintf(stderr, "bpp mismatch: first image (%s) is %d bpp, %s is %d bpp\n",
+                                       infiles[0], img.bpp, infiles[i], img.bpp);
+                       return 1;
+               }
+
+               overlay_key(&tmpimg, 0, &img);
+       }
+
        if(img.bpp == 4 && renibble) {
                unsigned char *ptr = img.pixels;
                for(i=0; i<img.width * img.height; i++) {
@@ -107,7 +123,8 @@ int main(int argc, char **argv)
                                printf("%d %d %d\n", img.cmap[i].r, img.cmap[i].g, img.cmap[i].b);
                        }
                } else {
-                       fwrite(img.cmap, sizeof img.cmap[0], img.cmap_ncolors, out);
+                       /*fwrite(img.cmap, sizeof img.cmap[0], img.cmap_ncolors, out);*/
+                       fwrite(img.cmap, sizeof img.cmap[0], 1 << img.bpp, out);
                }
                break;