- pngdump tool overlay multiple images (combine spritesheets)
[gba_blender] / src / main.c
index 0eeaa5a..2110b9a 100644 (file)
@@ -15,30 +15,99 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
+#include <stdlib.h>
 #include <string.h>
 #include "gbaregs.h"
 #include "timer.h"
 #include "keyb.h"
 #include "intr.h"
 #include "gfx.h"
+#include "xgl.h"
+#include "polyfill.h"
+#include "debug.h"
+#include "meshdata.h"
+#include "sprites.h"
+#include "dma.h"
+
+enum {
+       SIDX_DEL0, SIDX_DEL1, SIDX_DEL2,
+       SIDX_TIME,
+       SIDX_ICONS_BASE
+};
+
+#define SNAM_START     512
+enum {
+       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
+#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[];
 
+static int32_t cam_theta = 0x10000, cam_phi = -0x8000;
+
+static int show_obj = 1, show_del;
+
+#define AXIS0  0x10000
+#define AXIS1  0x80000
+
+static struct xvertex gridaxes[] = {
+       {AXIS0, 0, 0,   0, 0, 0, 92},
+       {AXIS1, 0, 0,   0, 0, 0, 92},
+       {-AXIS0, 0, 0,  0, 0, 0, 92},
+       {-AXIS1, 0, 0,  0, 0, 0, 92},
+       {0, 0, AXIS0,   0, 0, 0, 93},
+       {0, 0, AXIS1,   0, 0, 0, 93},
+       {0, 0, -AXIS0,  0, 0, 0, 93},
+       {0, 0, -AXIS1,  0, 0, 0, 93},
+
+       {0, 0, 0,               0, 0, 0, 92},
+       {AXIS1, 0, 0,   0, 0, 0, 92},
+       {0, 0, 0,               0, 0, 0, 92},
+       {-AXIS1, 0, 0,  0, 0, 0, 92},
+       {0, 0, 0,               0, 0, 0, 93},
+       {0, 0, AXIS1,   0, 0, 0, 93},
+       {0, 0, -0,              0, 0, 0, 93},
+       {0, 0, -AXIS1,  0, 0, 0, 93},
+};
+
+#define MAX_SIDX       8
+static uint16_t oam[4 * MAX_SIDX];
+
+
 int main(void)
 {
        int i;
+       unsigned int nframes = 0, backbuf;
        uint16_t *cptr;
        unsigned char r, g, b;
+       unsigned char *fbptr[2], *fb;
 
        intr_init();
        reset_msec_timer();
        set_intr();
 
        /* mode 4: 240x160 8bpp */
-       REG_DISPCNT = DISPCNT_BG2 | 4;
+       REG_DISPCNT = DISPCNT_BG2 | DISPCNT_OBJ | 4;
+
+       fbptr[0] = (unsigned char*)VRAM_LFB_FB0_ADDR;
+       fbptr[1] = (unsigned char*)VRAM_LFB_FB1_ADDR;
+
+       set_bg_color(0xff, 31, 31, 31);
 
        cptr = (uint16_t*)CRAM_BG_ADDR;
        for(i=0; i<128; i++) {
@@ -47,14 +116,79 @@ int main(void)
                b = bgimg_cmap[i].b >> 3;
                *cptr++ = r | (g << 5) | (b << 10);
        }
-       memcpy((void*)VRAM_LFB_FB0_ADDR, bgimg_pixels, 240 * 160);
-       memcpy((void*)VRAM_LFB_FB1_ADDR, bgimg_pixels, 240 * 160);
+       for(i=0; i<128; i++) {
+               r = i / 5 + 6;
+               *cptr++ = r | (r << 5) | (r << 10);
+       }
+       dma_copy16(3, fbptr[0], bgimg_pixels, 240 * 160 / 2, 0);
+       dma_copy16(3, fbptr[1], bgimg_pixels, 240 * 160 / 2, 0);
+
+       init_sprites();
+       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);
 
-       /*key_repeat(500, 75, KEY_LEFT | KEY_RIGHT | KEY_DOWN | KEY_UP);*/
+       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();
+
+               backbuf = ++nframes & 1;
+
+               fb = fbptr[backbuf] + 240 * MENU_HEIGHT;
+               polyfill_framebuffer(fb, 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);
+               xgl_rotate_x(cam_phi);
+               xgl_rotate_y(cam_theta);
+
+               if(show_obj) {
+                       if(cam_theta < X_PI) {
+                               xgl_draw(XGL_LINES, gridaxes + 2, 2);   /* -X */
+                       } else {
+                               xgl_draw(XGL_LINES, gridaxes, 2);               /* +X */
+                       }
+                       if(cam_theta < X_HPI || cam_theta > (3 * X_HPI)) {
+                               xgl_draw(XGL_LINES, gridaxes + 4, 2);   /* +Z */
+                       } else {
+                               xgl_draw(XGL_LINES, gridaxes + 6, 2);   /* -Z */
+                       }
+                       if(show_obj == 1) {
+                               xgl_draw(XGL_QUADS, cube, sizeof cube / sizeof *cube);
+                       } else {
+                               xgl_draw(XGL_TRIANGLES, suzanne, sizeof suzanne / sizeof *suzanne);
+                       }
+                       if(cam_theta < X_PI) {
+                               xgl_draw(XGL_LINES, gridaxes, 2);               /* +X */
+                       } else {
+                               xgl_draw(XGL_LINES, gridaxes + 2, 2);   /* -X */
+                       }
+                       if(cam_theta < X_HPI || cam_theta > (3 * X_HPI)) {
+                               xgl_draw(XGL_LINES, gridaxes + 6, 2);   /* -Z */
+                       } else {
+                               xgl_draw(XGL_LINES, gridaxes + 4, 2);   /* +Z */
+                       }
+               } else {
+                       xgl_draw(XGL_LINES, gridaxes + 8, 8);
+               }
+
                wait_vblank();
-               swap_buffers();
+               present(backbuf);
+               dma_copy16(3, (void*)OAM_ADDR, oam, sizeof oam / 2, 0);
        }
 
        return 0;
@@ -65,11 +199,57 @@ static void handle_keys(void)
        update_keyb();
 
        if(KEYPRESS(KEY_UP)) {
+               cam_phi += 0x2000;
+               if(cam_phi > X_HPI) cam_phi = X_HPI;
        }
        if(KEYPRESS(KEY_DOWN)) {
+               cam_phi -= 0x2000;
+               if(cam_phi < -X_HPI) cam_phi = -X_HPI;
        }
        if(KEYPRESS(KEY_LEFT)) {
+               cam_theta += 0x2000;
+               if(cam_theta > X_2PI) cam_theta -= X_2PI;
        }
        if(KEYPRESS(KEY_RIGHT)) {
+               cam_theta -= 0x2000;
+               if(cam_theta < 0) cam_theta += X_2PI;
+       }
+       if(KEYPRESS(KEY_RT)) {
+               if(++show_obj > 2) show_obj = 0;
+       }
+       if(KEYPRESS(KEY_LT)) {
+               if(--show_obj < 0) show_obj = 2;
+       }
+
+       if(KEYPRESS(KEY_A)) {
+               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, 50, 0,
+                                       SPR_SZ64 | SPR_BLEND);
+               }
+       } else {
+               for(i=0; i<3; i++) {
+                       set_sprite(oam, SIDX_DEL0 + i, 0, 0, 0, 0, 0);
+               }
        }
 }