// SPDX-License-Identiier: CC0-1.0
//
// SPDX-FileContributor: Michele Di Giorgio, 2024

// Example usage of maxmod song event. The ball moves in different positions
// based on SFx events.
//
// Credits to K. Jose for the audio track
// (https://modarchive.org/index.php?request=view_by_moduleid&query=193053).

#include <maxmod9.h>
#include <nds.h>

// This is autogenerated from ball.png and ball.grit
#include "ball.h"

#include "soundbank.h"
#include "soundbank_bin.h"

#include <stdio.h>

// Sprite coordinates
int spriteX = 80;
int spriteY = 80;

// Callback function that handles the song event
mm_word songEventHandler(mm_word message, mm_word param)
{
    switch (message) {
        case MMCB_SONGMESSAGE:
            if (param == 1) {
                spriteX = 60;
                spriteY = 80;
            } else if (param == 2) {
                spriteX = 40;
                spriteY = 80;
            } else if (param == 3) {
                spriteX = 80;
                spriteY = 60;
            } else if (param == 4) {
                spriteX = 80;
                spriteY = 40;
            } else if (param == 5) {
                spriteX = 80;
                spriteY = 80;
            }
            break;
        case MMCB_SONGFINISHED:
            break;
    }
    return 0;
}

int main(int argc, char **argv)
{
    consoleDemoInit();

    // Init video
    videoSetMode(MODE_0_2D);
    oamInit(&oamMain, SpriteMapping_1D_32, false);
    vramSetBankA(VRAM_A_MAIN_SPRITE);

    // Allocate space for the tiles and copy them there
    u16 *gfxMain = oamAllocateGfx(&oamMain, SpriteSize_32x32,
            SpriteColorFormat_256Color);
    memcpy(gfxMain, ballTiles, ballTilesLen);
    memcpy(SPRITE_PALETTE, ballPal, ballPalLen); // Copy palette

    // Init sound
    mmInitDefaultMem((mm_addr)soundbank_bin);

    mmSetEventHandler(songEventHandler);

    mmLoad(MOD_K_JOSE___GETAWAY);

    soundEnable();

    mmStart(MOD_K_JOSE___GETAWAY, MM_PLAY_LOOP);

    printf("maxmod song event example\n");
    printf("=========================\n");
    printf("\n");
    printf("START: Return to loader\n");

    oamSet(&oamMain, 0,
           spriteX, spriteY,
           0, // Priority
           0, // Palette index
           SpriteSize_32x32, SpriteColorFormat_256Color, // Size, Format
           gfxMain, // Graphics offset
           0, // Affine matrix index
           false, // Double size
           false, // Hide
           false, false, // H flip, V flip
           false); // Mosaic

    while (1) {
        scanKeys();

        uint16_t keys_down = keysDown();

        if (keys_down & KEY_START)
            break;

        oamSet(&oamMain, 0,
               spriteX, spriteY, // X, Y
               0, // Priority
               0, // Palette index
               SpriteSize_32x32, SpriteColorFormat_256Color, // Size, Format
               gfxMain, // Graphics offset
               0, // Affine matrix index
               false, // Double size
               false, // Hide
               false, false, // H flip, V flip
               false); // Mosaic

        swiWaitForVBlank();
        oamUpdate(&oamMain);
    }

    mmStop();
    soundDisable();

    oamFreeGfx(&oamMain, gfxMain);

    return 0;
}
