From 2cbb408ae15196bf4153fa6b17fb07fee6fe211b Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 16 Mar 2021 05:05:53 +0200 Subject: [PATCH] - fixed spritesheet conversion and setup - fixed dma_fills - started copying OAM from shadow on vblank --- Makefile | 2 +- src/dma.c | 20 ++++++++++--------- src/dma.h | 4 ++-- src/gbaregs.h | 39 ++++++++++++++++++++++++++----------- src/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++----- src/sprites.c | 2 +- tools/pngdump/main.c | 28 +++++++++++++++----------- 7 files changed, 108 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 9bb5113..33bb3d8 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ tools/pngdump/pngdump: $(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 $< diff --git a/src/dma.c b/src/dma.c index 78b516f..3d7606f 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,6 +1,6 @@ /* gbasys - a gameboy advance hardware abstraction library -Copyright (C) 2004-2014 John Tsiombikas +Copyright (C) 2004-2021 John Tsiombikas 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 @@ -44,34 +44,36 @@ static volatile unsigned long *reg_dma[4] = {(void*)0x040000b0, (void*)0x040000b /* --- 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; } diff --git a/src/dma.h b/src/dma.h index 96b1806..81dfe99 100644 --- a/src/dma.h +++ b/src/dma.h @@ -18,8 +18,8 @@ along with this program. If not, see . #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); diff --git a/src/gbaregs.h b/src/gbaregs.h index 762937f..a85b814 100644 --- a/src/gbaregs.h +++ b/src/gbaregs.h @@ -314,20 +314,37 @@ along with this program. If not, see . #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_ */ diff --git a/src/main.c b/src/main.c index 30d92c2..af2f6d3 100644 --- a/src/main.c +++ b/src/main.c @@ -29,11 +29,24 @@ along with this program. If not, see . #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[]; @@ -65,6 +78,10 @@ static struct xvertex gridaxes[] = { {0, 0, -AXIS1, 0, 0, 0, 93}, }; +#define MAX_SIDX 8 +static uint16_t oam[4 * MAX_SIDX]; + + int main(void) { int i; @@ -96,11 +113,10 @@ int main(void) 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); @@ -108,6 +124,10 @@ int main(void) 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(); @@ -115,7 +135,8 @@ int main(void) 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); @@ -154,6 +175,7 @@ int main(void) wait_vblank(); present(backbuf); + dma_copy16(3, (void*)OAM_ADDR, oam, sizeof oam / 2, 0); } return 0; @@ -187,12 +209,33 @@ static void handle_keys(void) } 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); } } } diff --git a/src/sprites.c b/src/sprites.c index 1986758..91471d7 100644 --- a/src/sprites.c +++ b/src/sprites.c @@ -41,7 +41,7 @@ void init_sprites(void) 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 */ } } diff --git a/tools/pngdump/main.c b/tools/pngdump/main.c index 908818d..a12fb3d 100644 --- a/tools/pngdump/main.c +++ b/tools/pngdump/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "image.h" void print_usage(const char *argv0); @@ -10,6 +11,7 @@ int main(int argc, char **argv) { int i, mode = 0; int text = 0; + int renibble = 0; char *fname = 0, *outfname = 0; struct image img; FILE *out = stdout; @@ -34,6 +36,10 @@ int main(int argc, char **argv) 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]); @@ -75,6 +81,14 @@ int main(int argc, char **argv) return 1; } + if(img.bpp == 4 && renibble) { + unsigned char *ptr = img.pixels; + for(i=0; i> 4); + } + } + if(outfname) { if(!(out = fopen(outfname, "wb"))) { fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno)); @@ -84,17 +98,7 @@ int main(int argc, char **argv) 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\n", argv0); printf("Options:\n"); + printf(" -o : 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"); } -- 1.7.10.4