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
-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 $<
.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"
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
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);
/* 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];
}
- /* 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;
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);
+ }
+ }
+ }
+}
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_ */
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++) {
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++) {
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;