- fixed spritesheet conversion and setup
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 16 Mar 2021 03:05:53 +0000 (05:05 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 16 Mar 2021 03:05:53 +0000 (05:05 +0200)
- fixed dma_fills
- started copying OAM from shadow on vblank

Makefile
src/dma.c
src/dma.h
src/gbaregs.h
src/main.c
src/sprites.c
tools/pngdump/main.c

index 9bb5113..33bb3d8 100644 (file)
--- 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 $<
index 78b516f..3d7606f 100644 (file)
--- 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 <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
@@ -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;
 }
index 96b1806..81dfe99 100644 (file)
--- a/src/dma.h
+++ b/src/dma.h
@@ -18,8 +18,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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);
index 762937f..a85b814 100644 (file)
@@ -314,20 +314,37 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #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_ */
index 30d92c2..af2f6d3 100644 (file)
@@ -29,11 +29,24 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #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);
                }
        }
 }
index 1986758..91471d7 100644 (file)
@@ -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 */
                }
        }
 
index 908818d..a12fb3d 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <assert.h>
 #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<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));
@@ -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<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:
@@ -127,9 +131,11 @@ void print_usage(const char *argv0)
 {
        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");
 }