[FEAT] play(str)
[FEAT] Chime on boot
[FEAT] simple song example on 'game.lua'
This commit is contained in:
2021-12-08 12:39:15 +01:00
parent 66bbdea85f
commit 77f31587f6
6 changed files with 151 additions and 27 deletions

View File

@@ -3,9 +3,14 @@
#include <string.h>
#include "lua.h"
#include "rom.c"
#include "play.h"
#define swap(a, b) {auto tmp=a;a=b;b=tmp;}
#define AUDIO_NONE 0
#define AUDIO_SOUND 1
#define AUDIO_PLAY 2
char lua_filename[1024];
char window_title[256];
uint8_t mem[8192]; //2400
@@ -17,7 +22,7 @@ uint8_t current_color = 0x1e;
uint8_t current_mode = 1;
uint8_t cursor_x = 0;
uint8_t cursor_y = 0;
bool sounding = false;
uint8_t audio_state = AUDIO_NONE;
int audio_freq = 0;
uint32_t audio_len = 0;
@@ -92,8 +97,13 @@ void reinit() {
}
}
static Uint8* play_pos;
static Uint32 play_len;
static Uint8 play_buffer[132300];
void audioCallback(void * userdata, uint8_t * stream, int len) {
//if (audio_len <= 0) nosound();
if (audio_state == AUDIO_SOUND) {
if (audio_len <= 0) audio_state = AUDIO_NONE;
static int period=0;
static int v = 16;
SDL_memset(stream, 0, len);
@@ -103,6 +113,26 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
stream[i] = v;
period++; if (period>=audio_freq) {period = 0; v=-v;}
}
} else if (audio_state == AUDIO_PLAY) {
while( len > 0 ) {
while( play_len == 0 ) {
play_len = interpret_next_token(play_buffer);
if (play_len == -1) { audio_state=AUDIO_NONE; SDL_memset( stream, 0, len ); return; }
play_pos = play_buffer;
}
const int actual_len = ( len > play_len ? play_len : len );
//SDL_memset( stream, 0, actual_len );
//SDL_MixAudio( stream, audio_pos, actual_len, SDL_MIX_MAXVOLUME );
SDL_memcpy(stream, play_pos, actual_len);
stream += actual_len;
play_pos += actual_len;
play_len -= actual_len;
len -= actual_len;
}
} else {
SDL_memset(stream, 0, len);
}
}
uint8_t old_mode = 0;
@@ -126,7 +156,7 @@ int main(int argc,char*argv[]) {
bool exit = false;
SDL_Event mini_eve;
SDL_AudioSpec audioSpec = {44100, AUDIO_S8, 1, 0, 512, 0, 0, audioCallback, NULL};
SDL_AudioSpec audioSpec = {22050, AUDIO_S8, 1, 0, 512, 0, 0, audioCallback, NULL};
mini_audio_device = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
SDL_PauseAudioDevice(mini_audio_device, 0);
@@ -480,14 +510,21 @@ void memcpy(uint16_t dst, uint16_t src, uint16_t size) {
void sound(float freq, uint32_t len) {
// [TODO]
audio_len = len*44.1f;
audio_freq = 44100.0f/freq/2.0f;
sounding = true;
audio_freq = 22050.0f/freq/2.0f;
audio_state = AUDIO_SOUND;
}
void nosound() {
//SDL_PauseAudioDevice(mini_audio_device, 1);
audio_len = 0;
sounding = false;
audio_state = AUDIO_NONE;
}
void play(const char* str) {
play_pos = play_buffer;
play_len = 0;
play_init(str);
audio_state = AUDIO_PLAY;
}
void setmode(const uint8_t mode) {

View File

@@ -170,8 +170,9 @@ void memcpy(uint16_t dst, uint16_t src, uint16_t size);
void sound(float freq, uint32_t len);
void nosound();
void setmode(const uint8_t mode);
void play(const char* str);
void setmode(const uint8_t mode);
void load(const char* str);
void fileout(const char* str, uint16_t addr, uint16_t size);

View File

@@ -1,17 +1,9 @@
function init()
setmode(0)
cls()
play("o4v5l1crcl4dcferl1crcl4dcgfr")
end
function update()
cls()
locate(0,0)
if mousebutton(1) then
print("Has pulsat el boto esquerre")
elseif mousebutton(2) then
print("Has pulsat el boto del mig")
elseif mousebutton(3) then
print("Has pulsat el boto dret")
else
print("No has pulsat cap boto")
end
end

View File

@@ -220,6 +220,12 @@ extern "C" {
return 0;
}
static int cpp_play(lua_State *L) {
const char* str = luaL_optstring(L, 1, NULL);
play(str);
return 0;
}
static int cpp_setmode(lua_State *L) {
int val = luaL_checkinteger(L, 1);
setmode(val);
@@ -268,7 +274,7 @@ bool lua_is_playing() {
return lua_state == STATE_PLAYING;
}
const char boot[] = "function init()setmode(1)cls()memcpy(360,4608,240)memcpy(1560,4848,240)ink(1)print('G A M E',8,16)ink(4)print('S Y S T E M',20,16)ink(8)print('v0.5.1',26,8)w=0 end function update()w=w+1 if w>90 then cls()load()end end";
const char boot[] = "function init()setmode(1)cls()play('o5l0v5cegv4cegv3cegv2cegv1ceg')memcpy(360,4608,240)memcpy(1560,4848,240)ink(1)print('G A M E',8,16)ink(4)print('S Y S T E M',20,16)ink(8)print('v0.5.1',26,8)w=0 end function update()w=w+1 if w>90 then cls()load()end end";
void lua_init(const char* filename, const bool start_playing) {
if (lua_state != STATE_STOPPED) lua_quit();
@@ -335,6 +341,7 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_memcpy); lua_setglobal(L, "memcpy");
lua_pushcfunction(L,cpp_sound); lua_setglobal(L, "sound");
lua_pushcfunction(L,cpp_nosound); lua_setglobal(L, "nosound");
lua_pushcfunction(L,cpp_play); lua_setglobal(L, "play");
lua_pushcfunction(L,cpp_setmode); lua_setglobal(L, "setmode");
lua_pushcfunction(L,cpp_load); lua_setglobal(L, "load");
lua_pushcfunction(L,cpp_log); lua_setglobal(L, "log");

81
play.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include "play.h"
#include <stdlib.h>
#include <string.h>
const static uint16_t lengths[10] = { 313, 625, 938, 1250, 1875, 2500, 3750, 5000, 7500, 10000 };
const static uint16_t tempos[10] = { 13230, 8820, 6615, 5292, 4410, 3780, 3308, 2940, 2646, 2406 };
const float periods[108] = { 1348.49207, 1272.80688, 1201.37, 1133.94214, 1070.29871, 1010.22772, 953.527893, 900.010376, 849.496887, 801.818176, 756.815613, 714.338745, 674.246033, 636.403564, 600.684875, 566.971069, 535.149475, 505.11377, 476.763947, 450.005249, 424.748352, 400.909088, 378.407806, 357.169373, 337.123016, 318.201782, 300.342438, 283.485535, 267.574738, 252.556885, 238.381973, 225.002625, 212.374176, 200.454544, 189.203888, 178.584702, 168.561508, 159.100876, 150.171234, 141.742767, 133.787354, 126.278458, 119.190987, 112.501305, 106.187096, 100.227272, 94.6019516, 89.2923508, 84.2807541, 79.5504379, 75.0856171, 70.8713837, 66.8936768, 63.139225, 59.5954933, 56.2506561, 53.0935478, 50.113636, 47.3009758, 44.6461754, 42.140377, 39.775219, 37.5428085, 35.4356918, 33.4468384, 31.5696125, 29.7977467, 28.1253281, 26.5467739, 25.056818, 23.650486, 22.3230877, 21.0701885, 19.8876095, 18.7714043, 17.7178459, 16.7234192, 15.7848072, 14.8988733, 14.0626631, 13.273387, 12.528409, 11.8252439, 11.1615429, 10.5350943, 9.94380569, 9.38570118, 8.85892296, 8.36171055, 7.89240265, 7.44943666, 7.03133202, 6.636693, 6.2642045, 5.91262197, 5.58077145, 5.26754713, 4.97190285, 4.69285059, 4.42946148, 4.18085527, 3.94620132, 3.72471833, 3.51566601, 3.3183465, 3.13210225, 2.95631051, 2.7903862 };
static float default_length = 0.25f;
static uint8_t volume = 64;
static uint8_t octave = 4;
static uint32_t tempo = 44100;
static char* song_ptr = NULL;
static char* song = NULL;
uint32_t interpret_note(uint8_t* buffer, const char note, const char param ) {
const uint32_t length = ( param == -1 ? default_length : ((float)lengths[param])/10000.0f ) * tempo;
if( note == 100 ) { memset( buffer, 0, length ); return length; }
const uint16_t period = periods[note + octave*12];
for( int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 1) ? volume : -volume );
return length;
}
void play_init(const char* new_song) {
if (song != NULL) free(song);
song = (char*)malloc( strlen( new_song ) + 1 );
strcpy( song, new_song );
song_ptr = song;
}
int32_t interpret_next_token(uint8_t* buffer) {
char** token = &song_ptr;
char note = 0;
char param = -1;
switch( **token ) {
case 'b': note += 2;
case 'a': note += 2;
case 'g': note += 2;
case 'f': note += 1;
case 'e': note += 2;
case 'd': note += 2;
case 'c':
param = *++*token;
if( param == '#' || param == '+' ) { note++; param = *++*token; } else if( param == '-' ) { note--; param = *++*token; }
if( param >= 48 && param <= 57 ) { param -= 48; ++*token; } else { param = -1; }
return interpret_note( buffer, note, param );
case 'r':
param = *++*token;
if( param >= 48 && param <= 57 ) { param -= 48; ++*token; } else { param = -1; }
return interpret_note( buffer, 100, param );
case 'o':
param = *++*token;
if( param >= 48 && param <= 57 ) { octave = (param - 48) % 8; ++*token; }
return 0;
case '>':
octave = (octave+1) % 8; ++*token;
return 0;
case '<':
octave = (octave-1) % 8; ++*token;
return 0;
case 'l':
param = *++*token;
if( param >= 48 && param <= 57 ) { default_length = ((float)lengths[param - 48])/10000.0f; ++*token; }
return 0;
case 'v':
param = *++*token;
if( param >= 48 && param <= 57 ) { volume = (param - 48) << 4; ++*token; }
return 0;
case 't':
param = *++*token;
if( param >= 48 && param <= 57 ) { tempo = tempos[param - 48] * 10; ++*token; }
return 0;
case '\0':
return -1;
default:
++*token;
return 0;
};
}

6
play.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
void play_init(const char* new_song);
int32_t interpret_next_token(uint8_t* buffer);