Files

334 lines
9.5 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
// VGM format sample
//─────────────────────────────────────────────────────────────────────────────
#include "msxgl.h"
#include "psg.h"
#include "wyz/wyz_player2.h"
//=============================================================================
// DEFINES
//=============================================================================
#define PLAYER_Y 4
// Library's logo
#define MSX_GL "\x02\x03\x04\x05"
// VGM music entry
struct MusicEntry
{
const c8* Name;
u16 Song;
u16 Inst;
u16 FX;
u16 Freq;
};
// Player button entry
struct ButtonEntry
{
u8 Char;
callback Func;
};
// Button callbacks
void ButtonPlay();
void ButtonPause();
void ButtonStop();
void ButtonPrev();
void ButtonNext();
void ButtonLoop();
// Music
extern u16 WYZ_songs;
extern u16 WYZ_instruments;
extern u16 WYZ_FXs;
extern u16 WYZ_notes;
extern u16 RA_PSG_Song;
extern u16 RA_PSG_Inst;
extern u16 RA_PSG_FX;
extern u16 RA_PSG_Freq;
extern u16 jinj_med_Song;
extern u16 jinj_med_Inst;
extern u16 jinj_med_FX;
extern u16 jinj_med_Freq;
extern u16 gothic_Song;
extern u16 gothic_Inst;
extern u16 gothic_FX;
extern u16 gothic_Freq;
extern u16 shampoo_Song;
extern u16 shampoo_Inst;
extern u16 shampoo_FX;
extern u16 shampoo_Freq;
extern u16 quezesto_Song;
extern u16 quezesto_Inst;
extern u16 quezesto_FX;
extern u16 quezesto_Freq;
//=============================================================================
// READ-ONLY DATA
//=============================================================================
// Fonts
#include "font/font_mgl_sample8.h"
// Animation characters
const u8 g_ChrAnim[] = { '|', '\\', '-', '/' };
// Music list
const struct MusicEntry g_MusicEntry[] =
{
{ "Jinj Med ", (u16)&jinj_med_Song, (u16)&jinj_med_Inst, (u16)&jinj_med_FX, (u16)&jinj_med_Freq },
{ "RA_PSG ", (u16)&RA_PSG_Song, (u16)&RA_PSG_Inst, (u16)&RA_PSG_FX, (u16)&RA_PSG_Freq },
{ "Nayade ", (u16)&WYZ_songs, (u16)&WYZ_instruments, (u16)&WYZ_FXs, (u16)&WYZ_notes },
{ "Gothic ", (u16)&gothic_Song, (u16)&gothic_Inst, (u16)&gothic_FX, (u16)&gothic_Freq },
{ "Shampoo ", (u16)&shampoo_Song, (u16)&shampoo_Inst, (u16)&shampoo_FX, (u16)&shampoo_Freq },
{ "Quezesto ", (u16)&quezesto_Song, (u16)&quezesto_Inst, (u16)&quezesto_FX, (u16)&quezesto_Freq },
};
// Player button list
const struct 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_CurrentButton;
bool g_Freq50Hz = FALSE;
bool g_DoLoop = TRUE;
//=============================================================================
// HELPER FUNCTIONS
//=============================================================================
//-----------------------------------------------------------------------------
//
void SetMusic(u8 idx)
{
g_CurrentMusic = idx;
const struct MusicEntry* entry = &g_MusicEntry[idx];
WYZ_Initialize(entry->Song, entry->Inst, entry->FX, entry->Freq);
// WYZ_PlaySong(0, g_DoLoop);
WYZ_Play(0);
Print_SetPosition(0, 2);
Print_DrawFormat("%i/%i %s", 1 + idx, numberof(g_MusicEntry), entry->Name);
}
//-----------------------------------------------------------------------------
//
void ButtonPlay()
{
// WYZ_Resume();
}
//-----------------------------------------------------------------------------
//
void ButtonPause()
{
// WYZ_Pause();
}
//-----------------------------------------------------------------------------
//
void ButtonStop()
{
WYZ_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;
// WYZ_SetLoop(g_DoLoop);
}
//-----------------------------------------------------------------------------
//
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);
}
//=============================================================================
// MAIN LOOP
//=============================================================================
//-----------------------------------------------------------------------------
// Program entry point
void main()
{
// Initialize screen
VDP_SetMode(VDP_MODE_SCREEN1);
VDP_SetColor2(COLOR_BLACK, COLOR_WHITE);
VDP_ClearVRAM();
VDP_EnableVBlank(TRUE);
// Initialize font
Print_SetTextFont(g_Font_MGL_Sample8, 1); // Initialize font
Print_DrawText(MSX_GL " WYZ2 SAMPLE");
Print_DrawLineH(0, 1, 32);
// Decode VGM header
SetMusic(0);
Print_DrawBox(0, PLAYER_Y, numberof(g_ButtonEntry) * 2 + 1, 3);
for (u8 i = 0; i < numberof(g_ButtonEntry); ++i)
{
Print_SetPosition(1 + 2 * i, PLAYER_Y+1);
Print_DrawChar(g_ButtonEntry[i].Char);
}
Print_SetPosition(0, PLAYER_Y+3);
Print_DrawText(" Chan A\n");
Print_DrawText(" Chan B\n");
Print_DrawText(" Chan C\n\n");
Print_SetPosition(0, 11);
Print_DrawText("Load:\n");
Print_DrawText("Playing:\n");
Print_DrawText("Effect:\n");
Print_DrawText("SFX:\n");
Print_DrawText("Loop:\n");
Print_DrawText("Ended:");
g_Freq50Hz = Sys_Is50Hz() ? 1 : 0;
Print_SetPosition(0, 18);
Print_DrawFormat("Freq: %s", (g_Freq50Hz) ? "50Hz" : "60Hz");
Print_SetPosition(20, 18);
Print_DrawFormat("BIOS: %s", Sys_Is50Hz() ? "50Hz" : "60Hz");
// Footer
Print_DrawLineH(0, 22, 32);
Print_SetPosition(0, 23);
Print_DrawText("\x8D:Button \x83:Action \x82:Freq Home:FX");
//-------------------------------------------------------------------------
// 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 (1)
{
Halt();
count++;
if (g_Freq50Hz || (count % 6 != 0))
{
WYZ_Decode();
#if (!WYZ_USE_DIRECT_ACCESS)
PSG_Apply();
#endif
}
VDP_SetSpriteColorSM1(0, g_ColorBlink[(count >> 2) & 0x03]);
// Print_SetPosition(8, 11); Print_DrawChar((g_WYZ_State & (1 << 0)) ? 0xC : 0xB);
// Print_SetPosition(8, 12); Print_DrawChar((g_WYZ_State & (1 << 1)) ? 0xC : 0xB);
// Print_SetPosition(8, 13); Print_DrawChar((g_WYZ_State & (1 << 2)) ? 0xC : 0xB);
// Print_SetPosition(8, 14); Print_DrawChar((g_WYZ_State & (1 << 3)) ? 0xC : 0xB);
// Print_SetPosition(8, 15); Print_DrawChar((g_WYZ_State & (1 << 4)) ? 0xC : 0xB);
// Print_SetPosition(8, 16); Print_DrawChar((g_WYZ_State & (1 << 7)) ? 0xC : 0xB);
Print_SetPosition(31, 0);
u8 chr = count & 0x03;
Print_DrawChar(g_ChrAnim[chr]);
// VU metter
u8* ayReg = (u8*)AYREGS + PSG_REG_AMP_A;
u8 y = PLAYER_Y+3;
loop (i, 3)
{
Print_SetPosition(8, y++);
if (*ayReg < 8)
{
u8 l = *ayReg & 0x07;
Print_DrawChar((l == 0) ? ' ' : 0xA0 + l);
Print_DrawChar(' ');
}
else // if (*ayReg >= 8)
{
Print_DrawChar(0xA0);
u8 h = *ayReg - 8;
Print_DrawChar((h == 0) ? ' ' : 0xA0 + h);
}
ayReg++;
}
// Handle input
u8 row8 = Keyboard_Read(8);
// Change button
if (IS_KEY_PRESSED(row8, KEY_RIGHT) && !IS_KEY_PRESSED(prevRow8, KEY_RIGHT))
{
SetCursor((g_CurrentButton < numberof(g_ButtonEntry) - 1) ? g_CurrentButton + 1 : 0);
}
else if (IS_KEY_PRESSED(row8, KEY_LEFT) && !IS_KEY_PRESSED(prevRow8, KEY_LEFT))
{
SetCursor((g_CurrentButton > 0) ? g_CurrentButton - 1 : numberof(g_ButtonEntry) - 1);
}
// Activate button
if (IS_KEY_PRESSED(row8, KEY_SPACE) && !IS_KEY_PRESSED(prevRow8, KEY_SPACE))
{
g_ButtonEntry[g_CurrentButton].Func();
}
// Change frequency
if ((IS_KEY_PRESSED(row8, KEY_UP) && !IS_KEY_PRESSED(prevRow8, KEY_UP)) || (IS_KEY_PRESSED(row8, KEY_DOWN) && !IS_KEY_PRESSED(prevRow8, KEY_DOWN)))
{
g_Freq50Hz = 1 - g_Freq50Hz;
Print_SetPosition(0, 18);
Print_DrawFormat("Freq: %s", (g_Freq50Hz) ? "50Hz" : "60Hz");
}
// Activate button
// if (IS_KEY_PRESSED(row8, KEY_HOME) && !IS_KEY_PRESSED(prevRow8, KEY_HOME))
// {
// WYZ_PlayFX(0);
// }
prevRow8 = row8;
}
}