Files
mazegame/projects/samples/s_ndp.c
T

306 lines
8.6 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
// NDP player sample
//─────────────────────────────────────────────────────────────────────────────
#include "msxgl.h"
#include "ndp/ndp_player.h"
//=============================================================================
// DEFINES
//=============================================================================
// Library's logo
#define MSX_GL "\x02\x03\x04\x05"
// Player Y coordinate
#define COPY_Y 7
#define TITLE_X 0
#define TITLE_Y 7
#define PLAYER_Y 3
#define QR_X 1
#define QR_Y 13
#define QR_PATTERN 192
// Player button entry
typedef struct
{
u8 Char;
callback Func;
} ButtonEntry;
// VGM music entry
typedef struct
{
const c8* Name;
void* Song;
void* FX;
} MusicEntry;
// Button callbacks
void ButtonPlay();
void ButtonPause();
void ButtonStop();
void ButtonPrev();
void ButtonNext();
void ButtonLoop();
//=============================================================================
// READ-ONLY DATA
//=============================================================================
// Fonts
#include "font/font_mgl_sample8.h"
// Song data
// DemoSongs by Naruto2413. All right reserved.
// https://naruto2413.bandcamp.com/album/ndp-demosongs
#include "content/ndp/NDP03.h"
#include "content/ndp/NDP04.h"
#include "content/ndp/NDP05.h"
#include "content/ndp/NDP09.h"
#include "content/ndp/NDP10.h"
#include "content/ndp/SE.h"
#include "content/img/naruto2413_qrcode.h"
// Music list
const MusicEntry g_MusicEntry[] =
{
{ "NDP Demo 03", g_NDP_NDP03, NULL },
{ "NDP Demo 04", g_NDP_NDP04, NULL },
{ "NDP Demo 05", g_NDP_NDP05, NULL },
{ "NDP Demo 09", g_NDP_NDP09, NULL },
{ "NDP Demo 10", g_NDP_NDP10, NULL },
};
// Animation characters
const u8 g_ChrAnim[] = { '|', '\\', '-', '/' };
// Player button list
const ButtonEntry g_ButtonEntry[] =
{
{ 0x80, ButtonPlay },
{ 0xB8, ButtonPause },
{ 0xB9, ButtonStop },
{ 0xBB, ButtonPrev },
{ 0xBA, ButtonNext },
{ 0xBE, ButtonLoop },
};
// Color shade
const u8 g_ColorBlink[4] = { COLOR_LIGHT_RED, COLOR_MEDIUM_RED, COLOR_DARK_RED, COLOR_MEDIUM_RED };
//=============================================================================
// MEMORY DATA
//=============================================================================
u8 g_CurrentMusic = 0;
u8 g_CurrentSFX = 0;
u8 g_CurrentButton;
bool g_Freq50Hz = FALSE;
bool g_DoLoop = TRUE;
u8 g_ButtonState[numberof(g_ButtonEntry)] = { 1, 0, 1, 1, 1, 1 };
//=============================================================================
// FUNCTIONS
//=============================================================================
//-----------------------------------------------------------------------------
//
void DrawPlayer()
{
Print_DrawBox(0, PLAYER_Y, numberof(g_ButtonEntry) * 2 + 1, 3);
for (u8 i = 0; i < numberof(g_ButtonEntry); ++i)
{
// Draw button icon
Print_SetPosition((i * 2) + 1, PLAYER_Y + 1);
Print_DrawChar(g_ButtonEntry[i].Char);
// Change icon color if disable
u16 addr = g_ScreenColorLow + ((g_PrintData.PatternOffset + g_ButtonEntry[i].Char) * 8);
VDP_FillVRAM(g_ButtonState[i] ? COLOR_MERGE(COLOR_WHITE, COLOR_BLACK) : COLOR_MERGE(COLOR_GRAY, COLOR_BLACK), addr, g_ScreenColorHigh, 8);
}
}
//-----------------------------------------------------------------------------
//
void SetMusic(u8 idx)
{
g_CurrentMusic = idx;
const MusicEntry* entry = &g_MusicEntry[idx];
NDP_Stop();
NDP_SetMusicData(entry->Song); // Set the song data address
NDP_Play(); // Start playing
Print_SetPosition(TITLE_X, TITLE_Y);
Print_DrawFormat("Music %i/%i: %s", 1 + idx, numberof(g_MusicEntry), entry->Name);
}
//-----------------------------------------------------------------------------
//
void SetSFX(u8 idx)
{
g_CurrentSFX = idx;
NDP_PlaySFX(g_CurrentSFX);
Print_SetPosition(TITLE_X, TITLE_Y + 1);
Print_DrawFormat("SFX %i/%i", 1 + idx, NDP_GetSFXNumber());
}
//-----------------------------------------------------------------------------
//
void ButtonPlay()
{
NDP_Play();
}
//-----------------------------------------------------------------------------
//
void ButtonPause()
{
}
//-----------------------------------------------------------------------------
//
void ButtonStop()
{
NDP_Stop();
}
//-----------------------------------------------------------------------------
//
void ButtonPrev()
{
if (g_CurrentMusic > 0)
SetMusic(g_CurrentMusic - 1);
}
//-----------------------------------------------------------------------------
//
void ButtonNext()
{
if (g_CurrentMusic < numberof(g_MusicEntry) - 1)
SetMusic(g_CurrentMusic + 1);
}
//-----------------------------------------------------------------------------
//
void ButtonLoop()
{
g_DoLoop = 1 - g_DoLoop;
g_ButtonState[5] = g_DoLoop;
DrawPlayer();
}
//-----------------------------------------------------------------------------
//
void SetCursor(u8 id)
{
g_CurrentButton = id;
VDP_SetSpriteSM1(0, 8 + 16*g_CurrentButton, ((PLAYER_Y+1)*8)-1, g_ButtonEntry[g_CurrentButton].Char, COLOR_LIGHT_RED);
}
//-----------------------------------------------------------------------------
// Program entry point
void main()
{
VDP_SetMode(VDP_MODE_SCREEN2); // Initialize screen mode 2 (GM2)
VDP_SetColor(COLOR_BLACK);
VDP_ClearVRAM();
Print_SetTextFont(g_Font_MGL_Sample8, 1); // Initialize font
Print_SetColor(COLOR_WHITE, COLOR_BLACK);
Print_DrawTextAt(0, 0, MSX_GL" NDP SAMPLE"); // Display title
Print_DrawLineH(0, 1, 32);
Print_SetPosition(0, QR_Y - 2);
Print_DrawText("https://naruto2413.bandcamp.com");
VDP_LoadPattern_GM2(g_QRCode_Patterns, 64, QR_PATTERN);
VDP_LoadColor_GM2(g_QRCode_Colors, 64, QR_PATTERN);
loop (i, 64)
{
u8 x = QR_X + (i & 0x7);
u8 y = QR_Y + (i >> 3);
VDP_Poke(i + QR_PATTERN, g_ScreenLayoutLow + (y * 32) + x, g_ScreenLayoutHigh);
}
Print_SetPosition(0, COPY_Y);
Print_DrawTextAt(QR_X + 9, QR_Y + 1, "DemoSongs");
Print_DrawTextAt(QR_X + 9, QR_Y + 3, "Naruto2413 \x0D 2024");
Print_DrawTextAt(QR_X + 9, QR_Y + 5, "All right reserved");
NDP_Initialize(); // Initialize the NDP player
NDP_SetSFXData(g_NDS_SE); // Set the SFX data address
// Decode VGM header
SetMusic(1);
DrawPlayer();
// Footer
Print_DrawLineH(0, 22, 32);
Print_DrawTextAt(0, 23, "\x8D:Button \x83:Action \x82:SFX");
// Sprite
VDP_SetSpriteFlag(VDP_SPRITE_SIZE_8 + VDP_SPRITE_SCALE_1);
VDP_LoadSpritePattern(g_Font_MGL_Sample8 + 4, 0, g_Font_MGL_Sample8[3] - g_Font_MGL_Sample8[2]);
SetCursor(4);
u8 prevRow8 = 0xFF;
u8 count = 0;
while(!Keyboard_IsKeyPressed(KEY_ESC))
{
Halt();
// VDP_SetColor(COLOR_DARK_BLUE);
NDP_Update();
// VDP_SetColor(COLOR_BLACK);
// Sing-of-life animation
Print_DrawCharAt(31, 0, g_ChrAnim[count++ & 0x03]);
// Cursor blink
VDP_SetSpriteColorSM1(0, g_ColorBlink[(count >> 2) & 0x03]);
// Automatic music transition when loop is disable and music reach its end
if (!g_DoLoop && NDP_HasMusicEnded())
{
SetMusic((g_CurrentMusic < numberof(g_MusicEntry) - 1) ? g_CurrentMusic + 1 : 0);
}
// Handle input
u8 row8 = Keyboard_Read(8);
// Change button
if (IS_KEY_PUSHED(row8, prevRow8, KEY_RIGHT))
{
SetCursor((g_CurrentButton < numberof(g_ButtonEntry) - 1) ? g_CurrentButton + 1 : 0);
}
else if (IS_KEY_PUSHED(row8, prevRow8, KEY_LEFT))
{
SetCursor((g_CurrentButton > 0) ? g_CurrentButton - 1 : numberof(g_ButtonEntry) - 1);
}
if (IS_KEY_PUSHED(row8, prevRow8, KEY_UP))
{
SetSFX(g_CurrentSFX < NDP_GetSFXNumber() - 1 ? g_CurrentSFX++ : 0);
}
else if (IS_KEY_PUSHED(row8, prevRow8, KEY_DOWN))
{
SetSFX(g_CurrentSFX > 0 ? g_CurrentSFX-- : NDP_GetSFXNumber() - 1);
}
// Activate button
if (IS_KEY_PUSHED(row8, prevRow8, KEY_SPACE))
{
g_ButtonEntry[g_CurrentButton].Func();
}
prevRow8 = row8;
}
NDP_Release(); // Release the NDP player
}