15 Commits

Author SHA1 Message Date
3979588f85 [FEATURE] toclipboard & fromclipboard 2021-12-13 20:02:17 +01:00
1618665124 [CHANGE] tostr() now accepts any type 2021-12-13 19:38:02 +01:00
527ab8bf01 [CHANGE] cls() sets cursor to (0,0) 2021-12-13 18:41:01 +01:00
62c513db56 [FEAT] crlf 2021-12-13 16:14:26 +01:00
e5798f4b71 [CHANGE] Print jumps to next line if needed 2021-12-13 15:09:30 +01:00
788c5d6c6e [FEAT] substr 2021-12-13 14:52:38 +01:00
0421f7f154 Music tool WIP 2021-12-13 10:44:38 +01:00
f11adb0557 added tetris (WIP) 2021-12-12 13:09:22 +01:00
3b7dd252ab Added demos and tools (WIP) 2021-12-12 12:53:22 +01:00
376c15c272 v0.5.4
[FEAT] Border
[FEAT] Color accepts a third optional parameter for border
2021-12-10 19:32:05 +01:00
f21f199917 [FEAT] Brackets enabled in console 2021-12-10 19:26:46 +01:00
12383f9309 [FEAT] Pong & Breakout included 2021-12-10 08:18:02 +01:00
d101da4a43 [BUG] volume, octave & tempo not reseting 2021-12-09 17:12:32 +01:00
d811790f66 [BUG] Versión not updated 2021-12-08 13:15:42 +01:00
77f31587f6 v0.5.2:
[FEAT] play(str)
[FEAT] Chime on boot
[FEAT] simple song example on 'game.lua'
2021-12-08 12:39:15 +01:00
13 changed files with 935 additions and 39 deletions

123
ascii.cpp
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
@@ -14,10 +19,11 @@ uint8_t *color_screen = NULL;
uint8_t screen_width = 40;
uint8_t screen_height = 30;
uint8_t current_color = 0x1e;
uint8_t current_border = 0;
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;
@@ -60,6 +66,7 @@ void reinit() {
screen_width = 80;
screen_height = 30;
current_color = 0x07;
current_border = 0;
cursor_x = 0;
cursor_y = 0;
char_screen = &mem[0];
@@ -71,6 +78,7 @@ void reinit() {
screen_width = 40;
screen_height = 30;
current_color = 0x07;
current_border = 0;
cursor_x = 0;
cursor_y = 0;
char_screen = &mem[0];
@@ -82,6 +90,7 @@ void reinit() {
screen_width = 20;
screen_height = 15;
current_color = 0x07;
current_border = 0;
cursor_x = 0;
cursor_y = 0;
char_screen = &mem[0];
@@ -92,16 +101,41 @@ 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();
static int period=0;
static int v = 16;
SDL_memset(stream, 0, len);
const int flen = min(audio_len, len);
audio_len -= flen;
for (int i=0; i<flen; ++i) {
stream[i] = v;
period++; if (period>=audio_freq) {period = 0; v=-v;}
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);
const int flen = min(audio_len, len);
audio_len -= flen;
for (int i=0; i<flen; ++i) {
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);
}
}
@@ -126,7 +160,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);
@@ -238,7 +272,7 @@ int main(int argc,char*argv[]) {
//for (int i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
SDL_UnlockTexture(mini_bak);
SDL_SetRenderDrawColor(mini_ren, (palette[0] >> 16)&0xff, (palette[0] >> 8)&0xff, palette[0]&0xff, 0);
SDL_SetRenderDrawColor(mini_ren, (palette[current_border] >> 16)&0xff, (palette[current_border] >> 8)&0xff, palette[current_border]&0xff, 0);
//SDL_SetRenderDrawColor(mini_ren, 255, 0, 0, 0);
SDL_RenderClear(mini_ren);
SDL_Rect rect = {40, 40, 640, 480};
@@ -260,6 +294,7 @@ void cls(uint8_t value) {
debug_prompt = 0;
debug_text[debug_prompt] = '>';
}
cursor_x = cursor_y = 0;
}
void ink(uint8_t value) {
@@ -270,8 +305,13 @@ void paper(uint8_t value) {
current_color = (current_color & 0x0f) + (value << 4);
}
void color(uint8_t ink, uint8_t paper) {
void border(uint8_t value) {
current_border = value & 0xf;
}
void color(uint8_t ink, uint8_t paper, int8_t border) {
current_color = (ink & 0x0f) + (paper << 4);
if (border >= 0) current_border = border & 0xf;
}
void locate(uint8_t x, uint8_t y) {
@@ -283,15 +323,22 @@ void print(const char *str, int x, int y) {
if (x >= 0) cursor_x = min(x, screen_width-1);
if (y >= 0) cursor_y = min(y, screen_height-1);
int len = SDL_strlen(str);
if ((cursor_x+len) > screen_width) len -= ((cursor_x+len) - screen_width);
const int pos = cursor_x+cursor_y*screen_width;
if (pos+len > screen_width*screen_height) len -= ((pos+len) - screen_width*screen_height);
//int offset = x+y*screen_width;
for (int i=0; i < len; ++i) {
CHRSCR(cursor_x+i, cursor_y) = str[i];
if (current_mode != 0) COLSCR(cursor_x+i, cursor_y) = current_color;
char_screen[pos+i] = str[i];
if (current_mode != 0) color_screen[pos+i] = current_color;
//char_screen[offset+i] = str[i];
//if (current_mode != 0) color_screen[offset+i] = current_color;
}
cursor_x += len;
cursor_x = (pos+len)%screen_width;
cursor_y = (pos+len)/screen_width;
}
void crlf() {
cursor_x=0;
cursor_y = min(cursor_y+1, screen_height-1);
}
bool btn(uint8_t i) {
@@ -384,9 +431,9 @@ int rnd(int x) {
srand(x);
}*/
char tostr_tmp[256];
char str_tmp[1024];
const char* tostr(float val) {
return SDL_itoa(val, tostr_tmp, 10);
return SDL_itoa(val, str_tmp, 10);
}
void debug_set_prompt() {
@@ -450,6 +497,12 @@ const char* chr(uint8_t ascii) {
return chr_trans;
}
const char* substr(const char* str, uint8_t start, uint8_t length) {
memcpy(str_tmp, &str[start], length);
str_tmp[length] = '\0';
return str_tmp;
}
void setchar(uint8_t index, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7) {
mem[MEM_CHAR_OFFSET+index*8] = b0;
mem[MEM_CHAR_OFFSET+index*8+1] = b1;
@@ -480,14 +533,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) {
@@ -511,3 +571,22 @@ void filein(const char* str, uint16_t addr, uint16_t size) {
fread(&mem[addr], size, 1, f);
fclose(f);
}
void toclipboard(const char* str) {
SDL_SetClipboardText(str);
}
const char* fromclipboard() {
char* text = SDL_GetClipboardText();
int len = strlen(text);
if (len > 1023) {
len = 27;
SDL_memcpy(str_tmp, "ERROR! CLIPBOARD TOO LARGE", len);
} else {
SDL_memcpy(str_tmp, text, len);
}
str_tmp[len] = '\0';
SDL_free((void*)text);
return str_tmp;
}

11
ascii.h
View File

@@ -115,10 +115,12 @@ void loop();
void cls(uint8_t value=32);
void ink(uint8_t value); // global::ink
void paper(uint8_t value); // global::paper
void color(uint8_t ink, uint8_t paper);
void border(uint8_t value);
void color(uint8_t ink, uint8_t paper, int8_t border=-1);
void locate(uint8_t x, uint8_t y); // global::cursorx, global::cursory
void print(const char *str, int x = -1, int y = -1);
void crlf();
bool btn(uint8_t i);
bool btnp(uint8_t i);
@@ -162,6 +164,7 @@ void debug_get_cmd();
uint8_t ascii(const char *str, uint8_t index);
const char* chr(uint8_t ascii);
const char* substr(const char* str, uint8_t start, uint8_t length);
void setchar(uint8_t index, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7);
uint8_t peek(uint16_t addr);
@@ -170,9 +173,13 @@ 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);
void filein(const char* str, uint16_t addr, uint16_t size);
void toclipboard(const char* str);
const char* fromclipboard();

94
demos/breakout.lua Normal file
View File

@@ -0,0 +1,94 @@
function init()
setmode(1)
reset()
end
function reset()
bx,by=20,28
dx,dy=-1+rnd(1)*2,-1
px=18
wait=1
speed=6
bricks = {}
for i=0,35 do bricks[i]=COLOR_RED end
for i=36,71 do bricks[i]=COLOR_BROWN end
for i=72,107 do bricks[i]=COLOR_GREEN end
for i=108,143 do bricks[i]=COLOR_YELLOW end
end
function update()
-- move ball
wait=wait-1
if wait==0 then
wait=speed
bx=bx+dx
by=by+dy
if speed<6 then
if bx==2 or bx==37 then dx=-dx play("o3l0c") end
if by<9 then
local index=flr(bx/2)-1+(by-1)*18
if bricks[index]~=COLOR_BLACK then
play("o5l0c")
bricks[index]=COLOR_BLACK
dy=-dy
else
if by==1 then dy=-dy play("o3l0c") end
end
end
if by==28 and bx>=px and bx<=px+4 then
play("o4l0c")
dy=-dy
end
if by==29 then
play("l0o3bagfedc")
reset()
end
else
if bx==2 or bx==37 then dx=-dx end
if by==9 or by==29 then dy=-dy end
end
end
-- move paddle
if btn(KEY_LEFT) and px>2 then px=px-1 end
if btn(KEY_RIGHT) and px<34 then px=px+1 end
-- clear screen
paper(COLOR_BLACK)
cls()
-- draw white border
ink(COLOR_WHITE)
print("\150\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\154\156",1,0)
for i=1,29 do
print("\149",1,i)
print("\149",38,i)
end
-- draw bricks
for i=0,143 do
color(0,bricks[i])
print("\095\003",2+2*(i%18),1+flr(i/18))
end
--draw ball
color(COLOR_WHITE,COLOR_BLACK)
print("\233",bx,by)
-- draw paddle
ink(COLOR_LIGHT_BLUE)
for i=0,3 do print("\131",px+i,29) end
if speed==6 then
ink(rnd(16))
print("BREAKOUT",16,13)
ink(COLOR_WHITE)
print("Press '1' to play EASY",9,18)
print("Press '2' to play NORMAL",8,20)
print("Press '3' to play HARD",9,22)
if btn(KEY_1) then reset() speed=4 end
if btn(KEY_2) then reset() speed=3 end
if btn(KEY_3) then reset() speed=2 end
end
end

140
demos/pong.lua Normal file
View File

@@ -0,0 +1,140 @@
function init()
setmode(1)
setchar(94, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
piano = { "_____", "\143\143\143\154\154", " ", "\143\143\143\154\154", "^^^^^", "_____",
"\143\143\143\154\154", " ", "\143\143\143\154\154", " ", "\143\143\143\154\154", "^^^^^" }
notes = {"C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "}
pnotes = {"c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"}
piano_pos=18
mousewait=0
compas = 0
compasos = {}
for i=0,31 do compasos[i] = 108 end
compasos[0] = 49
compasos[1] = 49
compasos[2] = 49
compasos[7] = 50
compasos[8] = 50
compasos[9] = 50
compasos[10] = 50
old_mouse_x,old_mouse_y = 0,0
end
function update()
color(COLOR_WHITE, COLOR_BLACK)
cls()
for i=0,11 do
local k = 11-i
local pos = ((piano_pos+i)%12)+1
local oct = flr((piano_pos+i)/12)+1
color(COLOR_WHITE, COLOR_BLACK)
print(notes[pos], 1, 10+k)
color(COLOR_BLACK, COLOR_WHITE)
print(piano[pos], 3, 10+k)
color(COLOR_BLACK, COLOR_LIGHT_GRAY+flr(oct%2))
print("_______\003_______\003_______\003_______\003", 8, 10+k)
color(COLOR_BLACK, oct)
if pos==6 then
print(tostr(oct), 0, 10+k)
else
print(" ", 0, 10+k)
end
end
piano_pos = mid(0, piano_pos+mousewheel(), 96)
if mousewait>0 then mousewait=mousewait-1 end
if mousebutton(1) and mousewait==0 then
if mousex()<8 and mousey()>=10 and mousey()<=21 then
local note = piano_pos+(11-(mousey()-10))
play("l4o"..tostr(note/12)..pnotes[(note%12)+1])
mousewait=10
end
end
for i=0,31 do
local n = compasos[i]
if n>=piano_pos and n<=piano_pos+11 then
if i>0 and n~=compasos[i-1] then
local oct = flr(n/12)+1
color(COLOR_BLACK, COLOR_LIGHT_GRAY+flr(oct%2))
print("\003",7+i,10+11-(n-piano_pos))
end
color(COLOR_BLACK,COLOR_LIGHT_RED)
if i==31 or compasos[i+1]~=n then
print("\003",8+i,10+11-(n-piano_pos))
else
print("_",8+i,10+11-(n-piano_pos))
end
end
end
if mousex()>=8 and mousey()>=10 and mousey()<=21 then
if mousebutton(1) then
compasos[mousex()-8] = piano_pos+11-(mousey()-10)
if old_mouse_x ~= mousex() or old_mouse_y ~= mousey() then
local note = piano_pos+11-(mousey()-10)
play("l4o"..tostr(note/12)..pnotes[(note%12)+1])
end
old_mouse_x,old_mouse_y = mousex(),mousey()
else
old_mouse_x,old_mouse_y = 0,0
if mousebutton(3) then
compasos[mousex()-8] = 108
end
end
end
if btnp(KEY_RETURN) then play_song() end
color(15,0)print("\143",0,0)
color(14,0)print("\143",1,0)
color(12,0)print("\143",2,0)
color(6,0)print("\143",3,0)
color(4,0)print("\143",4,0)
color(5,4)print("\143",5,0)
color(9,0)print("\143",6,0)
color(1,0)print("\143",7,0)
color(0,0)print("\143",8,0)
end
function play_song()
local note_size = {1,2,3,4,6,8,12,16,24,32}
local note_names = {"c","c#","d", "d#","e","f","f#","g","g#","a","a#","b"}
local song = ""
local current_note = 255
local current_octave = 4
local p=0
while p<32 do
current_note = compasos[p]
local d=0
while current_note == compasos[p] do d=d+1 p=p+1 end
local o = flr(current_note/12)
if o<9 and current_octave~=o then
current_octave=o
song=song.."o"..tostr(o)
end
local n = current_note%12
local note = note_names[n+1]
while d>0 do
local i=1
while d>note_size[i] do i=i+1 end
if note_size[i]>d then i=i-1 end
d=d-note_size[i]
if current_length~=i-1 then
current_length = i-1
song=song.."l"..tostr(i-1)
end
if o<9 then
song=song..note
else
song=song.."r"
end
end
end
play(song)
end

175
demos/tetris.lua Normal file
View File

@@ -0,0 +1,175 @@
--struct Tetromino { Uint16 figure; Uint8 orig, prev, next; };
tetromino = { {figure=0x0660, orig=0, prev=0, next=0}, {figure=0x4444, orig=1, prev=2, next=2}, {figure=0x0F00, orig=1, prev=1, next=1}, {figure=0x0C60, orig=2, prev=4, next=4}, {figure=0x2640, orig=2, prev=3, next=3}, {figure=0x06C0, orig=3, prev=6, next=6}, {figure=0x4620, orig=3, prev=5, next=5}, {figure=0x4460, orig=4, prev=8, next=10}, {figure=0x2E00, orig=4, prev=9, next=7}, {figure=0xC440, orig=4, prev=10, next=8}, {figure=0x0E80, orig=4, prev=7, next=9}, {figure=0x44C0, orig=5, prev=12, next=14}, {figure=0x0E20, orig=5, prev=13, next=11}, {figure=0x6440, orig=5, prev=14, next=12}, {figure=0x8E00, orig=5, prev=11, next=13}, {figure=0x4640, orig=6, prev=16, next=18}, {figure=0x4E00, orig=6, prev=17, next=15}, {figure=0x4C40, orig=6, prev=18, next=16}, {figure=0x0E40, orig=6, prev=15, next=17} }
starting = { 0, 1, 3, 5, 7, 11, 15 }
papers = { COLOR_LIGHT_RED, COLOR_LIGHT_GREEN, COLOR_LIGHT_BLUE, COLOR_YELLOW, COLOR_LIGHT_CYAN, COLOR_LIGHT_MAGENTA, COLOR_BROWN, COLOR_WHITE }
inks = { COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_BROWN, COLOR_CYAN, COLOR_MAGENTA, COLOR_RED, COLOR_LIGHT_GRAY }
--colors = {0x4c, 0x2a, 0x19, 0x6e, 0x3b, 0xd5, 0x56, 0x7f}
--Uint8 colors[8][3] { {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {0, 255, 255}, {255, 0, 255}, {255, 128, 0}, {255, 255, 255} };
board = {} --[20][10];
piece_pos = {x=3, y=0}
current_piece,next_piece,level,lines,score = 0,0,0,0,0
speed = (20-min(19, level))*3
function is_valid_move()
local x = piece_pos.x+3
local y = piece_pos.y+3
local piece = tetromino[current_piece+1].figure
for i=0,15 do
if ((piece & 1 == 1) and ( (x >= 10) or (x < 0) or (y >= 20) or (board[x+y*10] ~= 0) ) ) then return false end
piece = piece >> 1
x=x-1
if x < piece_pos.x then
x=piece_pos.x+3
y=y-1
end
end
return true
end
function check_lines()
local count = 0
local line = 19
while line > 0 do
local complete = true
for x=0,9 do
complete = (board[x+line*10] ~= 0)
if not complete then break end
end
if complete then
count=count+1
for y=line,1,-1 do
for x=0,9 do
board[x+y*10] = board[x+(y-1)*10]
end
end
else
line=line-1
end
end
lines=lines+count
local scoremult = {40,100,300,1200}
if count > 0 then score = score + scoremult[count] * (level+1) end
level = flr(lines / 10)
end
function fix_piece()
local x = piece_pos.x+3
local y = piece_pos.y+3
local piece = tetromino[current_piece+1].figure
for i=0,15 do
if piece & 1 == 1 then
board[x+y*10] = tetromino[current_piece+1].orig+1
end
piece = piece >> 1
x=x-1
if x < piece_pos.x then
x = piece_pos.x+3
y=y-1
end
end
piece_pos = {x=3, y=0}
current_piece = next_piece
next_piece = starting[rnd(7)+1]
check_lines()
end
function draw_cube(x,y,col)
color(inks[col+1],papers[col+1])
print("\001",x+1,y)
end
function draw_tetromino(init_x,init_y,piece_to_draw)
local x = init_x+3
local y = init_y+3
local piece = tetromino[piece_to_draw+1].figure
for i=0,15 do
if piece & 1 == 1 then
draw_cube(x, y, tetromino[piece_to_draw+1].orig)
end
piece = piece >> 1
x=x-1
if x < init_x then
x = init_x+3
y=y-1
end
end
end
--[[
void print(int x, int y, const char* text, Uint8 color) {
int cc = 0;
SDL_SetTextureColorMod(sdlTexture, colors[color][0], colors[color][1], colors[color][2]);
SDL_Rect src {0, 0, 8, 8}, dst {x, y, 16, 16};
while (text[cc] != 0) {
if (text[cc] == 32) continue;
else if (text[cc] >= 65) { src.x = ((text[cc]-65)%6)*8; src.y = ((text[cc]-65)/6)*8; }
else if (text[cc] < 65) { src.x = ((text[cc]-22)%6)*8; src.y = ((text[cc]-22)/6)*8; }
SDL_RenderCopy(sdlRenderer, sdlTexture, &src, &dst);
cc++; dst.x+=16;
}
}
--]]
function init()
setmode(1)
current_piece = starting[rnd(7)+1]
next_piece = starting[rnd(7)+1]
piece_pos = {x=3, y=0}
level,lines,score = 0,0,0
speed = (20-min(19, level))*3
for i=0,20*10 do board[i] = 0 end
setchar(1,0xff,0x81,0x81,0x81,0x81,0x81,0x81,0xff)
border(COLOR_BLUE)
end
function update()
if btnp(KEY_RIGHT) then
piece_pos.x = piece_pos.x + 1
if not is_valid_move() then piece_pos.x=piece_pos.x-1 end
end
if btnp(KEY_LEFT) then
piece_pos.x = piece_pos.x - 1
if not is_valid_move() then piece_pos.x=piece_pos.x+1 end
end
if btnp(KEY_DOWN) then
piece_pos.y = piece_pos.y + 1
if not is_valid_move() then piece_pos.y=piece_pos.y-1 end
end
if btnp(KEY_UP) then
current_piece = tetromino[current_piece+1].next
if not is_valid_move() then current_piece = tetromino[current_piece+1].prev end
end
paper(COLOR_BLACK)
cls()
ink(COLOR_BLUE) print("LEVEL "..tostr(level), 3, 5) -- color 2
ink(COLOR_RED) print("SCORE "..tostr(score), 3, 7) -- color 0
ink(COLOR_GREEN) print("LINES "..tostr(lines), 3, 9) -- color 1
color(COLOR_DARK_GRAY,COLOR_LIGHT_GRAY)
for i=0,20 do print ("\001",14,i+5) print("\001",25,i+5) end
print("\001\001\001\001\001\001\001\001\001\001\001\001",14,25)
for y=0,19 do
for x=0,9 do
if board[x+y*10] ~= 0 then
draw_cube(14+x, y+5, board[x+y*10]-1)
end
end
end
draw_tetromino(27, 5, next_piece)
draw_tetromino(14+piece_pos.x, 5+piece_pos.y, current_piece)
speed=speed-1
if speed == 0 then
speed = (20-min(19, level))*3
piece_pos.y=piece_pos.y+1
if not is_valid_move() then
piece_pos.y=piece_pos.y-1
if piece_pos.y==0 then
init()
else
fix_piece()
play("c")
end
end
end
end

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

153
lua.cpp
View File

@@ -2,6 +2,86 @@
#include "lua/lua.hpp"
#include "ascii.h"
void reverse(char* str, int len) {
int i = 0, j = len - 1, temp;
while (i < j) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
i++;
j--;
}
}
int intToStr(int x, char str[], int d) {
int i = 0;
while (x) {
str[i++] = (x % 10) + '0';
x = x / 10;
}
while (i < d) str[i++] = '0';
reverse(str, i);
str[i] = '\0';
return i;
}
int ftoa(float n, char* res, int afterpoint) {
int ipart = (int)n;
float fpart = n - (float)ipart;
int i = intToStr(ipart, res, 1);
fpart = fpart * SDL_pow(10, afterpoint);
if (int(fpart) != 0) {
res[i++] = '.';
i += intToStr((int)fpart, res + i, afterpoint);
while(res[i-1] == '0') res[--i] = '\0';
}
return i;
}
char tempstr[1024];
uint16_t ts_index = 0;
void table_to_str(lua_State *L, int indx);
void value_to_str(lua_State *L, int indx) {
if (lua_isnoneornil(L, indx)) {
SDL_memcpy(&tempstr[ts_index], "nil", 3); ts_index+=3;
} else if (lua_isfunction(L, indx) || lua_iscfunction(L,indx)) {
SDL_memcpy(&tempstr[ts_index], "[function]", 10); ts_index+=10;
} else if (lua_istable(L, indx)) {
table_to_str(L, indx);
} else if (lua_type(L, indx) == LUA_TNUMBER) {
const float val = luaL_checknumber(L, indx);
const int len = ftoa(val, &tempstr[ts_index], 4); ts_index+=len;
} else if (lua_isboolean(L,indx)) {
if (lua_toboolean(L, indx)) {
SDL_memcpy(&tempstr[ts_index], "true", 4); ts_index+=4;
} else {
SDL_memcpy(&tempstr[ts_index], "false", 5); ts_index+=5;
}
} else if (lua_isstring(L,indx)) {
const char* str = luaL_checkstring(L,indx);
tempstr[ts_index++] = '"';
SDL_memcpy(&tempstr[ts_index], str, strlen(str)); ts_index+=strlen(str);
tempstr[ts_index++] = '"';
}
}
void table_to_str(lua_State *L, int indx) {
tempstr[ts_index++] = '{';
lua_pushnil(L);
bool first = true;
while (lua_next(L, indx) != 0) {
if (first) { first=false; } else { tempstr[ts_index++] = ','; }
value_to_str(L, lua_gettop(L)-1);
tempstr[ts_index++] = '=';
value_to_str(L, lua_gettop(L));
lua_pop(L, 1);
}
tempstr[ts_index++] = '}';
}
extern "C" {
static int cpp_cls(lua_State *L) {
uint8_t color = luaL_optinteger(L, 1, 32);
@@ -21,10 +101,21 @@ extern "C" {
return 0;
}
static int cpp_border(lua_State *L) {
uint8_t val = luaL_checkinteger(L, 1);
border(val);
return 0;
}
static int cpp_color(lua_State *L) {
uint8_t ink = luaL_checkinteger(L, 1);
uint8_t paper = luaL_checkinteger(L, 2);
color(ink, paper);
if (lua_gettop(L) > 2) {
uint8_t border = luaL_checkinteger(L, 3);
color(ink, paper, border);
} else {
color(ink, paper);
}
return 0;
}
@@ -43,6 +134,11 @@ extern "C" {
return 0;
}
static int cpp_crlf(lua_State *L) {
crlf();
return 0;
}
static int cpp_btn(lua_State *L) {
uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, btn(i));
@@ -152,9 +248,28 @@ extern "C" {
return 0;
}
static int cpp_tostr(lua_State *L) {
float val = luaL_checknumber(L, 1);
lua_pushstring(L, tostr(val));
ts_index=0;
value_to_str(L, 1); tempstr[ts_index] = '\0';
lua_pushstring(L, tempstr);
return 1;
/*
if (lua_isnoneornil(L,1)) {
lua_pushstring(L, "nil");
} else if (lua_isfunction(L,1) || lua_iscfunction(L,1)) {
lua_pushstring(L, "[function]");
} else if (lua_istable(L,1)) {
lua_gettable
lua_pushstring(L, "[function]");
} else if (lua_isstring(L,1)) {
lua_pushstring(L, luaL_checkstring(L,1));
} else if (lua_isboolean(L,1)) {
lua_pushstring(L, lua_toboolean(L, 1) ? "true" : "false");
} else {
const float val = luaL_checknumber(L, 1);
lua_pushstring(L, tostr(val));
}
return 1;
*/
}
static int cpp_ascii(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
@@ -172,6 +287,13 @@ extern "C" {
lua_pushinteger(L, strlen(str));
return 1;
}
static int cpp_substr(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
int start = luaL_checknumber(L, 2);
int length = luaL_checknumber(L, 3);
lua_pushstring(L, substr(str, start, length));
return 1;
}
static int cpp_setchar(lua_State *L) {
int index = luaL_checkinteger(L, 1);
@@ -220,6 +342,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);
@@ -253,6 +381,17 @@ extern "C" {
filein(str, addr, size);
return 0;
}
static int cpp_toclipboard(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
toclipboard(str);
return 0;
}
static int cpp_fromclipboard(lua_State *L) {
lua_pushstring(L, fromclipboard());
return 1;
}
}
#define STATE_STOPPED 0
@@ -268,7 +407,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(7)print('mini',9,8)ink(8)print('v0.5.4',34,29)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();
@@ -297,10 +436,12 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_cls); lua_setglobal(L, "cls");
lua_pushcfunction(L,cpp_ink); lua_setglobal(L, "ink");
lua_pushcfunction(L,cpp_paper); lua_setglobal(L, "paper");
lua_pushcfunction(L,cpp_border); lua_setglobal(L, "border");
lua_pushcfunction(L,cpp_color); lua_setglobal(L, "color");
lua_pushcfunction(L,cpp_locate); lua_setglobal(L, "locate");
lua_pushcfunction(L,cpp_print); lua_setglobal(L, "print");
lua_pushcfunction(L,cpp_crlf); lua_setglobal(L, "crlf");
lua_pushcfunction(L,cpp_btn); lua_setglobal(L, "btn");
lua_pushcfunction(L,cpp_btnp); lua_setglobal(L, "btnp");
@@ -328,6 +469,7 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_ascii); lua_setglobal(L, "ascii");
lua_pushcfunction(L,cpp_chr); lua_setglobal(L, "chr");
lua_pushcfunction(L,cpp_strlen); lua_setglobal(L, "strlen");
lua_pushcfunction(L,cpp_substr); lua_setglobal(L, "substr");
lua_pushcfunction(L,cpp_setchar); lua_setglobal(L, "setchar");
lua_pushcfunction(L,cpp_peek); lua_setglobal(L, "peek");
@@ -335,12 +477,15 @@ 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");
lua_pushcfunction(L,cpp_fileout); lua_setglobal(L, "fileout");
lua_pushcfunction(L,cpp_filein); lua_setglobal(L, "filein");
lua_pushcfunction(L,cpp_toclipboard); lua_setglobal(L, "toclipboard");
lua_pushcfunction(L,cpp_fromclipboard); lua_setglobal(L, "fromclipboard");
lua_pushinteger(L, 0); lua_setglobal(L, "KEY_UNKNOWN");
lua_pushinteger(L, 4); lua_setglobal(L, "KEY_A");

View File

@@ -32,6 +32,8 @@ void do_terminal() {
else if (key == KEY_COMMA) { if (mods & KMOD_SHIFT) { debugchr(';'); } else { debugchr(','); } }
else if (key == KEY_PERIOD) { if (mods & KMOD_SHIFT) { debugchr(':'); } else { debugchr('.'); } }
else if (key == KEY_SLASH) { if (mods & KMOD_SHIFT) { debugchr('_'); } else { debugchr('-'); } }
else if (key == KEY_LEFTBRACKET) { if (mods & KMOD_SHIFT) { debugchr(160); } else if (mods & KMOD_RALT) { debugchr('['); } else { debugchr(96); } }
else if (key == KEY_RIGHTBRACKET) { if (mods & KMOD_SHIFT) { debugchr('*'); } else if (mods & KMOD_RALT) { debugchr(']'); } else { debugchr('+'); } }
}
//cls(0);
pdebug();

84
play.cpp Normal file
View File

@@ -0,0 +1,84 @@
#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) {
volume=64;
octave=4;
tempo=44100;
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);

172
tools/music.lua Normal file
View File

@@ -0,0 +1,172 @@
function init()
setmode(1)
setchar(94, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
piano = { "_____", "\143\143\143\154\154", " ", "\143\143\143\154\154", "^^^^^", "_____",
"\143\143\143\154\154", " ", "\143\143\143\154\154", " ", "\143\143\143\154\154", "^^^^^" }
notes = {"C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "}
pnotes = {"c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"}
piano_pos=18
mousewait=0
compas = 0
compasos = {}
for i=0,1279 do compasos[i] = 108 end
compasos[0] = 49
compasos[1] = 49
compasos[2] = 49
compasos[7] = 50
compasos[8] = 50
compasos[9] = 50
compasos[10] = 50
old_mouse_x,old_mouse_y = 0,0
end
function update()
color(COLOR_WHITE, COLOR_BLACK)
cls()
ink(COLOR_BLACK)
for i=0,39 do
if (i==compas) then paper(COLOR_LIGHT_RED) else paper(COLOR_LIGHT_GRAY) end
print("___\003",(i%10)*4,flr(i/10)+5)
end
if mousebutton(1) and mousey()<=8 and mousey()>=5 then
compas = flr(mousex()/4)+(mousey()-5)*10
end
for i=0,11 do
local k = 11-i
local pos = ((piano_pos+i)%12)+1
local oct = flr((piano_pos+i)/12)+1
color(COLOR_WHITE, COLOR_BLACK)
print(notes[pos], 1, 10+k)
color(COLOR_BLACK, COLOR_WHITE)
print(piano[pos], 3, 10+k)
color(COLOR_BLACK, COLOR_LIGHT_GRAY+flr(oct%2))
print("_______\003_______\003_______\003_______\003", 8, 10+k)
color(COLOR_BLACK, oct)
if pos==6 then
print(tostr(oct), 0, 10+k)
else
print(" ", 0, 10+k)
end
end
piano_pos = mid(0, piano_pos+mousewheel(), 96)
if mousewait>0 then mousewait=mousewait-1 end
if mousebutton(1) and mousewait==0 then
if mousex()<8 and mousey()>=10 and mousey()<=21 then
local note = piano_pos+(11-(mousey()-10))
play("l4o"..tostr(note/12)..pnotes[(note%12)+1])
mousewait=10
end
end
for i=0,31 do
local n = compasos[(compas*32)+i]
if n>=piano_pos and n<=piano_pos+11 then
if i>0 and n~=compasos[(compas*32)+i-1] then
local oct = flr(n/12)+1
color(COLOR_BLACK, COLOR_LIGHT_GRAY+flr(oct%2))
print("\003",7+i,10+11-(n-piano_pos))
end
color(COLOR_BLACK,COLOR_LIGHT_RED)
if i==31 or compasos[(compas*32)+i+1]~=n then
print("\003",8+i,10+11-(n-piano_pos))
else
print("_",8+i,10+11-(n-piano_pos))
end
end
end
if mousex()>=8 and mousey()>=10 and mousey()<=21 then
if mousebutton(1) then
compasos[(compas*32)+mousex()-8] = piano_pos+11-(mousey()-10)
if old_mouse_x ~= mousex() or old_mouse_y ~= mousey() then
local note = piano_pos+11-(mousey()-10)
play("l4o"..tostr(note/12)..pnotes[(note%12)+1])
end
old_mouse_x,old_mouse_y = mousex(),mousey()
else
old_mouse_x,old_mouse_y = 0,0
if mousebutton(3) then
compasos[(compas*32)+mousex()-8] = 108
end
end
end
if btnp(KEY_RETURN) then
if btn(KEY_LSHIFT) then
play_song(true)
else
play_song()
end
end
color(15,0)print("\143",0,0)
color(14,0)print("\143",1,0)
color(12,0)print("\143",2,0)
color(6,0)print("\143",3,0)
color(4,0)print("\143",4,0)
color(5,4)print("\143",5,0)
color(9,0)print("\143",6,0)
color(1,0)print("\143",7,0)
color(0,0)print("\143",8,0)
end
function search_song_end()
local i = 1279
while i>0 and compasos[i] == 108 do i=i-1 end
return i+1
end
function play_song(entire_song)
entire_song = entire_song or false
local note_size = {1,2,3,4,6,8,12,16,24,32}
local note_names = {"c","c#","d", "d#","e","f","f#","g","g#","a","a#","b"}
local song = ""
local current_note = 255
local current_octave = 4
local p=compas*32
local ends=32+compas*32
if entire_song then
p=0
ends=search_song_end()
end
while p<ends do
current_note = compasos[p]
local d=0
while d<32 and current_note == compasos[p] do d=d+1 p=p+1 end
local o = flr(current_note/12)
if o<9 and current_octave~=o then
current_octave=o
song=song.."o"..tostr(o)
end
local n = current_note%12
local note = note_names[n+1]
while d>0 do
local i=1
while d>note_size[i] do i=i+1 end
if note_size[i]>d then i=i-1 end
d=d-note_size[i]
if current_length~=i-1 then
current_length = i-1
song=song.."l"..tostr(i-1)
end
if o<9 then
song=song..note
else
song=song.."r"
end
end
end
log(song)
play(song)
end