mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-18 18:07:35 +00:00
105 lines
9.9 KiB
C
105 lines
9.9 KiB
C
|
|
||
|
/*
|
||
|
Demonstrates playing multi-voice music on the PSG
|
||
|
using the CPC BIOS functions.
|
||
|
|
||
|
Similar to the music example in "Making Arcade Games in C".
|
||
|
*/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "cpctelera.h"
|
||
|
|
||
|
#include "sound_bios.h"
|
||
|
//#link "sound_bios.c"
|
||
|
|
||
|
#include "music.h"
|
||
|
|
||
|
typedef unsigned char byte;
|
||
|
typedef unsigned short word;
|
||
|
|
||
|
//
|
||
|
// MUSIC ROUTINES
|
||
|
//
|
||
|
|
||
|
void music_start(const byte* music);
|
||
|
void music_update();
|
||
|
|
||
|
// Namespace(length=64, upper=49, freq=62500.0, bias=0, maxbits=12)
|
||
|
// 430.0 4.526547151857908 49
|
||
|
const int note_table[64] = {
|
||
|
2464,2326,2195,2072,1956,1846,1742,1644,1552,1465,1383,1305,1232,1163,1098,1036,978,923,871,822,776,733,691,653,616,581,549,518,489,461,436,411,388,366,346,326,308,291,274,259,244,231,218,206,194,183,173,163,154,145,137,129,122,115,109,103,97,92,86,82,77,73,69,65,};
|
||
|
|
||
|
struct {
|
||
|
byte volume;
|
||
|
} voice[3];
|
||
|
|
||
|
byte music_index = 0;
|
||
|
byte cur_duration = 0;
|
||
|
byte num_voices = 3;
|
||
|
|
||
|
static const byte* music_ptr = NULL;
|
||
|
|
||
|
inline byte next_music_byte() {
|
||
|
return *music_ptr++;
|
||
|
}
|
||
|
|
||
|
void music_update() {
|
||
|
byte ch;
|
||
|
byte freech = 0;
|
||
|
for (ch=0; ch<num_voices; ch++) {
|
||
|
if (voice[ch].volume) {
|
||
|
voice[ch].volume--;
|
||
|
} else {
|
||
|
freech = ch;
|
||
|
}
|
||
|
}
|
||
|
if (music_ptr) {
|
||
|
ch = freech;
|
||
|
while (cur_duration == 0) {
|
||
|
byte note = next_music_byte();
|
||
|
if ((note & 0x80) == 0) {
|
||
|
int period = note_table[note & 63];
|
||
|
sound(ch+1, period, 5, 15, 1, 0, 0);
|
||
|
voice[ch].volume = 31;
|
||
|
ch = ch ? ch-1 : num_voices-1;
|
||
|
} else {
|
||
|
if (note == 0xff)
|
||
|
music_ptr = NULL;
|
||
|
cur_duration = note & 63;
|
||
|
}
|
||
|
}
|
||
|
cur_duration--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void music_start(const byte* music) __critical {
|
||
|
music_ptr = music;
|
||
|
cur_duration == 0;
|
||
|
}
|
||
|
|
||
|
///
|
||
|
/// MUSIC TEST
|
||
|
///
|
||
|
|
||
|
#ifdef __MAIN__
|
||
|
|
||
|
const byte music1[] = {
|
||
|
0x38,0x8c,0x3a,0x88,0x20,0x81,0x23,0x82,0x28,0x81,0x3b,0x32,0x2c,0xa4,0x3a,0x8c,0x38,0x32,0x2c,0x91,0x1f,0x83,0x22,0x83,0x27,0x81,0x37,0x31,0x2e,0xa4,0x35,0x2c,0x8c,0x37,0x31,0x2e,0x90,0x20,0x83,0x23,0x83,0x27,0x82,0x38,0x2f,0x27,0xbf,0x85,0x20,0x81,0x23,0x82,0x27,0x81,0x38,0x2f,0x27,0xb0,0x2c,0x2c,0x20,0x98,0x2f,0x2c,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x31,0x2e,0x27,0x98,0x33,0x2f,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x34,0x31,0x20,0x8c,0x33,0x2f,0x27,0x98,0x31,0x2e,0x2a,0x8c,0x1e,0x8c,0x22,0x8c,0x1e,0x8c,0x2e,0x2a,0x25,0x98,0x2a,0x2a,0x2a,0x8c,0x1e,0x8c,0x22,0x8c,0x2c,0x2c,0x29,0x8c,0x2e,0x2e,0x28,0x98,0x2f,0x2c,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x2c,0x27,0x23,0x98,0x2c,0x26,0x23,0x8c,0x1c,0x8c,0x23,0x8c,0x2b,0x22,0x20,0x8c,0x2c,0x26,0x20,0x98,0x2e,0x27,0x1f,0x8c,0x1b,0x8c,0x1f,0x8c,0x1b,0x8c,0x22,0x8c,0x1f,0x8c,0x27,0x27,0x1f,0x8c,0x22,0x8c,0x2b,0x98,0x2c,0x2c,0x20,0x98,0x2f,0x2c,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x31,0x2e,0x27,0x98,0x33,0x2f,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x34,0x31,0x20,0x8c,0x33,0x2f,0x27,0x98,0x31,0x2e,0x2a,0x8c,0x1e,0x8c,0x22,0x8c,0x1e,0x8c,0x2e,0x2a,0x25,0x98,0x2a,0x2a,0x2a,0x8c,0x1e,0x8c,0x22,0x8c,0x2c,0x2c,0x29,0x8c,0x2e,0x2e,0x28,0x98,0x2f,0x2c,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x2e,0x25,0x20,0x8c,0x2c,0x27,0x23,0x98,0x2b,0x27,0x22,0x8c,0x1b,0x8c,0x22,0x8c,0x29,0x20,0x1f,0x8c,0x2b,0x27,0x22,0x98,0x2c,0x27,0x23,0x8c,0x1b,0x8c,0x20,0x8c,0x1b,0x8c,0x27,0x8c,0x23,0x8c,0x2c,0x27,0x23,0x8c,0x1b,0x8c,0x20,0x8c,0x22,0x8c,0x23,0x8c,0x27,0x8c,0x36,0x33,0x2a,0x8c,0x23,0x8c,0x2a,0x8c,0x27,0x8c,0x1e,0x8c,0x23,0x8c,0x36,0x33,0x2a,0x8c,0x27,0x8c,0x2a,0x8c,0x35,0x31,0x27,0x8c,0x33,0x2f,0x2a,0x8c,0x23,0x8c,0x31,0x2e,0x2a,0x8c,0x22,0x8c,0x2a,0x8c,0x25,0x8c,0x2e,0x2a,0x25,0x8c,0x22,0x8c,0x2a,0x2a,0x2a,0x8c,0x25,0x8c,0x2a,0x8c,0x2c,0x2c,0x29,0x8c,0x2e,0x2e,0x28,0x8c,0x22,0x8c,0x2f,0x2c,0x27,0x8c,0x23,0x8c,0x27,0x8c,0x23,0x8c,0x2c,0x27,0x23,0x8c,0x23,0x8c,0x2c,0x26,0x23,0x8c,0x23,0x8c,0x28,0x8c,0x2b,0x22,0x23,0x8c,0x2c,0x26,0x20,0x8c,0x23,0x8c,0x2e,0x27,0x1f,0x8c,0x1f,0x8c,0x22,0x8c,0x27,0x8c,0x2b,0x27,0x22,0x8c,0x1f,0x8c,0x27,0x27,0x27,0x8c,0x22,0x8c,0x27,0x8c,0x2b,0x8c,0x27,0x8c,0x22,0x8c,0x36,0x33,0x2a,0x8c,0x23,0x8c,0x27,0x8c,0x2a,0x8c,0x23,0x8c,0x27,0x8c,0x36,0x33,0x2a,0x8c,0x23,0x8c,0x27,0x8c,0x35,0x31,0x2a,0x8c,0x33,0x2f,0x2a,0x8c,0x27,0x8c,0x31,0x2e,0x2a,0x8c,0x22,0x8c,0x25,0x8c,0x2a,0x8c,0x2e,0x2a,0x25,0x8c,0x25,0x8c,0x2a,0x2a,0x2a,0x8c,0x22,0x8c,0x25,0x8c,0x2c,0x2c,0x29,0x8c,0x2e,0x2e,0x28,0x8c,0x22,0x8c,0x2f,0x2c,0x27,0x8c,0x23,0x8c,0x27,0x8c,0x2e,0x25,0x20,0x8c,0x2c,0x27,0x23,0x8c,0x23,0x8c,0x2b,0x27,0x22,0x8c,0x22,0x8c,0x27,0x8c,0x29,0x20,0x2b,0x8c,0x2b,0x27,0x22,0x8c,0x22,0x8c,0x2c,0x27,0x23,0x8c,0x23,0x8c,0x28,0x25,0x25,0x8c,0x20,0x8c,0x25,0x22,0x28,0x8c,0x25,0x8c,0x2c,0x27,0x23,0xb0,0x38,0x8c,0x3a,0x88,0x20,0x81,0x23,0x82,0x28,0x81,0x3b,0x32,0x2c,0xa4,0x3a,0x8c,0x38,0x32,0x2c,0x91,0x1f,0x83,0x22,0x83,0x27,0x81,0x37,0x31,0x2e,0xa4,0x35,0x2c,0x8c,0x37,0x31,0x2e,0x90,0x20,0x83,0x23,0x83,0x27,0x82,0x38,0x2f,0x27,0xbf,0x85,0x20,0x81,0x23,0x82,0x27,0x81,0x38,0x2f,0x27,0xb0,0x20,0x98,0x23,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x25,0x27,0x98,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x28,0x20,0x8c,0x27,0x27,0x98,0x25,0x8c,0x1e,0x8c,0x22,0x8c,0x1e,0x8c,0x22,0x25,0x98,0x1e,0x8c,0x1e,0x8c,0x22,0x8c,0x20,0x1e,0x8c,0x22,0x25,0x98,0x23,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x20,0x27,0x98,0x20,0x8c,0x1c,0x8c,0x23,0x8c,0x1f,0x20,0x8c,0x20,0x28,0x98,0x22,0x8c,0x1b,0x8c,0x1f,0x8c,0x1b,0x8c,0x22,0x8c,0x1f,0x8c,0x1b,0x27,0x8c,0x22,0x8c,0x2b,0x98,0x20,0x98,0x23,0x20,0x8c,0x1b,0x8c,0x23,0x8c,0x20,0x8c,0x25,0x27,0x98,0x27,0x8c,0x1b,0x8c,0x23,0x8c,0x28,0x20,0x8c,0x27,0x27,0x98,0x25,0x8c,0x1e,0x8c,0x22,0x8c,0x1e,0x8c,0x22,0x25,0x98,0x1e,0x8c,0x1e,0x8c,0x22,0x8c,0x20,0x1e,0x8c,0x22,0x25,0x98,0x23,0x8c,0x1b,0x8c,0x23,0x8c,0x22,0x20,0x8c,0x20,0x27,0x98,0x1f,0x8c,0x1b,0x8c,0x22,0x8c,0x1d,0x1f,0x8c,0x1f,0x27,0x98,0x20,0x8c,0x1b,0x8c,0x20,0x8c,0x1b,0x8c,0x27,0x8c,0x23,0x8c,0x20,0x20,0x8c,0x1b,0x8c,0x20,0x8c,0x22,0x8c,0x23,0x8c,0x27,0x8c,0x27,0x2a,0x20,0x8c,0x23,0x8c,0x2a,0x8c,0x27,0x8c,0x1e,0x8c,0x23,0x8c,0x27,0x2a,0x1e,0x8c,0x27,0x8c,0x2a,
|
||
|
};
|
||
|
|
||
|
void delay(int n) {
|
||
|
while (n--) cpct_waitVSYNC();
|
||
|
}
|
||
|
|
||
|
void main(void) {
|
||
|
env(1, 25, 15, 1);
|
||
|
while (1) {
|
||
|
if (!music_ptr) music_start(music1);
|
||
|
music_update();
|
||
|
delay(6);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|