$(MAKE) -C tools/pngdump
%.raw: %.png tools/pngdump/pngdump
- tools/pngdump/pngdump -o $@ $<
+ tools/pngdump/pngdump -o $@ -n $<
%.pal: %.png tools/pngdump/pngdump
tools/pngdump/pngdump -o $@ -c $<
/*
gbasys - a gameboy advance hardware abstraction library
-Copyright (C) 2004-2014 John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2004-2021 John Tsiombikas <nuclear@member.fsf.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* --- perform a copy of words or halfwords using DMA --- */
-void dma_copy32(int channel, void *dst, void *src, int words)
+void dma_copy32(int channel, void *dst, void *src, int words, unsigned int flags)
{
reg_dma[channel][DMA_SRC] = (unsigned long)src;
reg_dma[channel][DMA_DST] = (unsigned long)dst;
- reg_dma[channel][DMA_CTRL] = words | DMA_TIMING_IMMED | DMA_32 | DMA_ENABLE;
+ reg_dma[channel][DMA_CTRL] = words | flags | DMA_32 | DMA_ENABLE;
}
-void dma_copy16(int channel, void *dst, void *src, int halfwords)
+void dma_copy16(int channel, void *dst, void *src, int halfwords, unsigned int flags)
{
reg_dma[channel][DMA_SRC] = (unsigned long)src;
reg_dma[channel][DMA_DST] = (unsigned long)dst;
- reg_dma[channel][DMA_CTRL] = halfwords | DMA_TIMING_IMMED | DMA_16 | DMA_ENABLE;
+ reg_dma[channel][DMA_CTRL] = halfwords | flags | DMA_16 | DMA_ENABLE;
}
/* --- fill a buffer with an ammount of words and halfwords using DMA --- */
+static unsigned long fill[4];
+
void dma_fill32(int channel, void *dst, unsigned long val, int words)
{
- unsigned long valmem = val;
- reg_dma[channel][DMA_SRC] = (unsigned long)&valmem;
+ fill[channel] = val;
+ reg_dma[channel][DMA_SRC] = (unsigned long)(fill + channel);
reg_dma[channel][DMA_DST] = (unsigned long)dst;
reg_dma[channel][DMA_CTRL] = words | DMA_SRC_FIX | DMA_TIMING_IMMED | DMA_32 | DMA_ENABLE;
}
void dma_fill16(int channel, void *dst, unsigned short val, int halfwords)
{
- unsigned short valmem = val;
- reg_dma[channel][DMA_SRC] = (unsigned long)&valmem;
+ fill[channel] = val;
+ reg_dma[channel][DMA_SRC] = (unsigned long)(fill + channel);
reg_dma[channel][DMA_DST] = (unsigned long)dst;
reg_dma[channel][DMA_CTRL] = halfwords | DMA_SRC_FIX | DMA_TIMING_IMMED | DMA_16 | DMA_ENABLE;
}
#ifndef _DMA_H_
#define _DMA_H_
-void dma_copy32(int channel, void *dst, void *src, int words);
-void dma_copy16(int channel, void *dst, void *src, int halfwords);
+void dma_copy32(int channel, void *dst, void *src, int words, unsigned int flags);
+void dma_copy16(int channel, void *dst, void *src, int halfwords, unsigned int flags);
void dma_fill32(int channel, void *dst, unsigned long val, int words);
void dma_fill16(int channel, void *dst, unsigned short val, int halfwords);
#define SCNT_DSB_CLRFIFO 0x8000
/* REG_DMAxCNT_H bits */
+#define DMACNTH_DST_INC 0
+#define DMACNTH_DST_DEC 0x0020
+#define DMACNTH_DST_FIXED 0x0040
+#define DMACNTH_INC_RELOAD 0x0060
+#define DMACNTH_SRC_INC 0
+#define DMACNTH_SRC_DEC 0x0080
+#define DMACNTH_SRC_FIXED 0x0100
+#define DMACNTH_REPEAT 0x0200
+#define DMACNTH_16BIT 0
+#define DMACNTH_32BIT 0x0400
+#define DMACNTH_VBLANK 0x1000
+#define DMACNTH_HBLANK 0x2000
+#define DMACNTH_SOUND 0x3000
+#define DMACNTH_IEN 0x4000
+#define DMACNTH_EN 0x8000
+
#define DMACNT_DST_INC 0
-#define DMACNT_DST_DEC 0x0020
-#define DMACNT_DST_FIXED 0x0040
+#define DMACNT_DST_DEC 0x00200000
+#define DMACNT_DST_FIXED 0x00400000
+#define DMACNT_INC_RELOAD 0x00600000
#define DMACNT_SRC_INC 0
-#define DMACNT_SRC_DEC 0x0080
-#define DMACNT_SRC_FIXED 0x0100
-#define DMACNT_REPEAT 0x0200
+#define DMACNT_SRC_DEC 0x00800000
+#define DMACNT_SRC_FIXED 0x01000000
+#define DMACNT_REPEAT 0x02000000
#define DMACNT_16BIT 0
-#define DMACNT_32BIT 0x0400
-#define DMACNT_VBLANK 0x1000
-#define DMACNT_HBLANK 0x2000
-#define DMACNT_SOUND 0x3000
-#define DMACNT_IEN 0x4000
-#define DMACNT_EN 0x8000
+#define DMACNT_32BIT 0x04000000
+#define DMACNT_VBLANK 0x10000000
+#define DMACNT_HBLANK 0x20000000
+#define DMACNT_SOUND 0x30000000
+#define DMACNT_IEN 0x40000000
+#define DMACNT_EN 0x80000000
#endif /* GBAREGS_H_ */
#include "sprites.h"
#include "dma.h"
+enum {
+ SIDX_DEL0, SIDX_DEL1, SIDX_DEL2,
+ SIDX_TIME,
+ SIDX_ICONS_BASE
+};
+
+enum {
+ SNAM_DEL0 = 512,
+ SNAM_DEL1 = SNAM_DEL0 + 8,
+ SNAM_DEL2 = SNAM_DEL1 + 8
+};
+
#define MENU_HEIGHT 17
#define TRACK_HEIGHT 18
#define VP_HEIGHT (160 - MENU_HEIGHT - TRACK_HEIGHT)
static void handle_keys(void);
+static void show_msgbox(int en);
extern struct { unsigned char r, g, b; } bgimg_cmap[];
extern unsigned char bgimg_pixels[];
{0, 0, -AXIS1, 0, 0, 0, 93},
};
+#define MAX_SIDX 8
+static uint16_t oam[4 * MAX_SIDX];
+
+
int main(void)
{
int i;
r = i / 5 + 6;
*cptr++ = r | (r << 5) | (r << 10);
}
- dma_copy16(3, fbptr[0], bgimg_pixels, 240 * 160 / 2);
- dma_copy16(3, fbptr[1], bgimg_pixels, 240 * 160 / 2);
+ dma_copy16(3, fbptr[0], bgimg_pixels, 240 * 160 / 2, 0);
+ dma_copy16(3, fbptr[1], bgimg_pixels, 240 * 160 / 2, 0);
init_sprites();
- set_sprite(0, 0, 512, 42, 42, 0, SPR_SZ64);
xgl_init();
xgl_viewport(0, 0, 240, VP_HEIGHT);
key_repeat(75, 75, KEY_LEFT | KEY_RIGHT | KEY_DOWN | KEY_UP);
+ /* every vblank, copy the shadow OAM automatically */
+ /*dma_copy16(3, (void*)OAM_ADDR, oam, sizeof oam / 2, DMACNT_VBLANK |
+ DMACNT_REPEAT | DMACNT_INC_RELOAD);*/
+
for(;;) {
handle_keys();
fb = fbptr[backbuf] + 240 * MENU_HEIGHT;
polyfill_framebuffer(fb, 240, VP_HEIGHT);
- memset(fb, 14, 240 * VP_HEIGHT);
+ //memset(fb, 14, 240 * VP_HEIGHT);
+ dma_fill16(3, fb, 0x0e0e, 240 * VP_HEIGHT / 2);
xgl_load_identity();
xgl_translate(0, 0, 8 << 16);
wait_vblank();
present(backbuf);
+ dma_copy16(3, (void*)OAM_ADDR, oam, sizeof oam / 2, 0);
}
return 0;
}
if(KEYPRESS(KEY_A)) {
- show_del ^= 1;
+ if(!show_del) {
+ if(show_obj) show_del = 1;
+ } else {
+ show_del = 0;
+ }
+ show_msgbox(show_del);
}
if(KEYPRESS(KEY_B)) {
if(show_del) {
show_obj = 0;
show_del = 0;
+ show_msgbox(0);
+ }
+ }
+}
+
+static void show_msgbox(int en)
+{
+ int i;
+
+ if(en) {
+ for(i=0; i<3; i++) {
+ set_sprite(oam, SIDX_DEL0 + i, SNAM_DEL0 + i * 8, 42 + i * 64, 42, 0, SPR_SZ64);
+ }
+ } else {
+ for(i=0; i<3; i++) {
+ set_sprite(oam, SIDX_DEL0 + i, 0, 0, 0, 0, 0);
}
}
}
src += 2;
if((i & 31) == 31) {
- src += 7 * 128; /* skip to the next row of tiles */
+ src += 7 * 64; /* skip to the next row of tiles */
}
}
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "image.h"
void print_usage(const char *argv0);
{
int i, mode = 0;
int text = 0;
+ int renibble = 0;
char *fname = 0, *outfname = 0;
struct image img;
FILE *out = stdout;
text = 1;
break;
+ case 'n':
+ renibble = 1;
+ break;
+
case 'o':
if(!argv[++i]) {
fprintf(stderr, "%s must be followed by a filename\n", argv[i - 1]);
return 1;
}
+ if(img.bpp == 4 && renibble) {
+ unsigned char *ptr = img.pixels;
+ for(i=0; i<img.width * img.height; i++) {
+ unsigned char p = *ptr;
+ *ptr++ = (p << 4) | (p >> 4);
+ }
+ }
+
if(outfname) {
if(!(out = fopen(outfname, "wb"))) {
fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
switch(mode) {
case 0:
- if(img.bpp > 8 || img.cmap_ncolors == 0 || img.cmap_ncolors > 16) {
- fwrite(img.pixels, 1, img.scansz * img.height, out);
- } else {
- /* pack into nibbles */
- unsigned char *ptr = img.pixels;
- for(i=0; i<img.width * img.height / 2; i++) {
- unsigned char pair = (ptr[0] << 4) | ptr[1];
- fputc(pair, out);
- ptr += 2;
- }
- }
+ fwrite(img.pixels, 1, img.scansz * img.height, out);
break;
case 1:
{
printf("Usage: %s [options] <input file>\n", argv0);
printf("Options:\n");
+ printf(" -o <output file>: specify output file (default: stdout)\n");
printf(" -p: dump pixels (default)\n");
printf(" -c: dump colormap (palette) entries\n");
printf(" -i: print image information\n");
printf(" -t: dump as text\n");
+ printf(" -n: swap the order of nibbles (for 4bpp)\n");
printf(" -h: print usage and exit\n");
}