21 Commits

Author SHA1 Message Date
56f2e202e8 [WIP] Defender clone 2021-12-15 19:58:58 +01:00
9b1573be9d Code editor WIP 2021-12-15 19:24:56 +01:00
11bb1b5283 Code Editor WIP 2021-12-15 12:16:36 +01:00
acfaf873ce Code Editor WIP 2021-12-14 20:09:23 +01:00
be083a23e2 [FEAT] New terminal console system 2021-12-14 15:59:14 +01:00
63ca77e3e6 New console system WIP 2021-12-14 12:42:09 +01:00
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
14 changed files with 1572 additions and 153 deletions

271
ascii.cpp
View File

@@ -3,9 +3,17 @@
#include <string.h> #include <string.h>
#include "lua.h" #include "lua.h"
#include "rom.c" #include "rom.c"
#include "play.h"
#include <vector>
#include <string>
#define swap(a, b) {auto tmp=a;a=b;b=tmp;} #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 lua_filename[1024];
char window_title[256]; char window_title[256];
uint8_t mem[8192]; //2400 uint8_t mem[8192]; //2400
@@ -14,10 +22,11 @@ uint8_t *color_screen = NULL;
uint8_t screen_width = 40; uint8_t screen_width = 40;
uint8_t screen_height = 30; uint8_t screen_height = 30;
uint8_t current_color = 0x1e; uint8_t current_color = 0x1e;
uint8_t current_border = 0;
uint8_t current_mode = 1; uint8_t current_mode = 1;
uint8_t cursor_x = 0; uint8_t cursor_x = 0;
uint8_t cursor_y = 0; uint8_t cursor_y = 0;
bool sounding = false; uint8_t audio_state = AUDIO_NONE;
int audio_freq = 0; int audio_freq = 0;
uint32_t audio_len = 0; uint32_t audio_len = 0;
@@ -37,22 +46,21 @@ int pitch;
uint32_t palette[16] = { 0x00000000, 0x000000AA, 0x0000AA00, 0x0000AAAA, 0x00AA0000, 0x00AA00AA, 0x00AA5500, 0x00AAAAAA, uint32_t palette[16] = { 0x00000000, 0x000000AA, 0x0000AA00, 0x0000AAAA, 0x00AA0000, 0x00AA00AA, 0x00AA5500, 0x00AAAAAA,
0x00555555, 0x005555FF, 0x0055FF55, 0x0055FFFF, 0x00FF5555, 0x00FF55FF, 0x00FFFF55, 0x00FFFFFF }; 0x00555555, 0x005555FF, 0x0055FF55, 0x0055FFFF, 0x00FF5555, 0x00FF55FF, 0x00FFFF55, 0x00FFFFFF };
#define debug_line_size 80 int debug_prompt = -1;
#define debug_num_lines 30
#define debug_total_size 2400 //debug_line_size*debug_num_lines
char debug_text[debug_total_size];
int debug_cursor = 0;
int debug_prompt = 0;
int debug_cursor_blink = 30; int debug_cursor_blink = 30;
std::vector<std::string> cmd_list;
bool should_reset = false; bool should_reset = false;
//Uint8 keymapping[6] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_Z, SDL_SCANCODE_X };
const Uint8 *keys; const Uint8 *keys;
Uint8 key_just_pressed = 0; Uint8 key_just_pressed = 0;
int mouse_x, mouse_y, mouse_wheel; int mouse_x, mouse_y, mouse_wheel;
Uint32 mouse_buttons; Uint32 mouse_buttons;
const char* get_filename() {
return lua_filename;
}
void reinit() { void reinit() {
if (mini_bak != NULL) SDL_DestroyTexture(mini_bak); if (mini_bak != NULL) SDL_DestroyTexture(mini_bak);
switch (current_mode) { switch (current_mode) {
@@ -60,6 +68,7 @@ void reinit() {
screen_width = 80; screen_width = 80;
screen_height = 30; screen_height = 30;
current_color = 0x07; current_color = 0x07;
current_border = 0;
cursor_x = 0; cursor_x = 0;
cursor_y = 0; cursor_y = 0;
char_screen = &mem[0]; char_screen = &mem[0];
@@ -71,6 +80,7 @@ void reinit() {
screen_width = 40; screen_width = 40;
screen_height = 30; screen_height = 30;
current_color = 0x07; current_color = 0x07;
current_border = 0;
cursor_x = 0; cursor_x = 0;
cursor_y = 0; cursor_y = 0;
char_screen = &mem[0]; char_screen = &mem[0];
@@ -82,6 +92,7 @@ void reinit() {
screen_width = 20; screen_width = 20;
screen_height = 15; screen_height = 15;
current_color = 0x07; current_color = 0x07;
current_border = 0;
cursor_x = 0; cursor_x = 0;
cursor_y = 0; cursor_y = 0;
char_screen = &mem[0]; char_screen = &mem[0];
@@ -89,11 +100,28 @@ void reinit() {
//SDL_RenderSetLogicalSize(mini_ren, 160, 120); //SDL_RenderSetLogicalSize(mini_ren, 160, 120);
mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 120); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 120);
break; break;
case 3: // SUPERSECRET MODE FOR THE EDITOR!!!
screen_width = 80;
screen_height = 30;
current_color = 0x1f;
current_border = 9;
cursor_x = 0;
cursor_y = 0;
char_screen = &mem[0];
color_screen = &mem[0x1200];
//SDL_RenderSetLogicalSize(mini_ren, 640, 480);
mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 240);
break;
} }
} }
static Uint8* play_pos;
static Uint32 play_len;
static Uint8 play_buffer[132300];
void audioCallback(void * userdata, uint8_t * stream, int len) { 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 period=0;
static int v = 16; static int v = 16;
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
@@ -103,6 +131,26 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
stream[i] = v; stream[i] = v;
period++; if (period>=audio_freq) {period = 0; v=-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; uint8_t old_mode = 0;
@@ -111,11 +159,13 @@ void romcpy() {
SDL_memcpy(&mem[2560], rom, rom_size); SDL_memcpy(&mem[2560], rom, rom_size);
} }
void debug_set_prompt();
int main(int argc,char*argv[]) { int main(int argc,char*argv[]) {
SDL_strlcpy(lua_filename, "game.lua", 9); SDL_strlcpy(lua_filename, "game.lua", 9);
if (argc > 1) SDL_strlcpy(lua_filename, argv[1], 1023); if (argc > 1) SDL_strlcpy(lua_filename, argv[1], 1023);
for (int i=0; i<debug_total_size;++i) debug_text[i] = 32; //[TODEL]for (int i=0; i<debug_total_size;++i) debug_text[i] = 32;
SDL_Init(49); SDL_Init(49);
mini_win = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640+80, 480+80, SDL_WINDOW_SHOWN); mini_win = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640+80, 480+80, SDL_WINDOW_SHOWN);
@@ -126,7 +176,7 @@ int main(int argc,char*argv[]) {
bool exit = false; bool exit = false;
SDL_Event mini_eve; 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); mini_audio_device = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
SDL_PauseAudioDevice(mini_audio_device, 0); SDL_PauseAudioDevice(mini_audio_device, 0);
@@ -153,15 +203,19 @@ int main(int argc,char*argv[]) {
if (lua_is_playing()) { if (lua_is_playing()) {
lua_pause(); lua_pause();
//lua_quit(); //lua_quit();
old_mode = current_mode; debug_set_prompt();
setmode(0); //old_mode = current_mode;
//setmode(0);
} else { } else {
setmode(old_mode); //setmode(old_mode);
lua_resume(); lua_resume();
//lua_init(); //lua_quit();
//reinit();
//lua_init(lua_filename);
//lua_call_init(); //lua_call_init();
} }
} else if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F5) { } else if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F5) {
execute_run();
lua_quit(); lua_quit();
reinit(); reinit();
lua_init(lua_filename); lua_init(lua_filename);
@@ -181,11 +235,13 @@ int main(int argc,char*argv[]) {
if (lua_is_playing()) { if (lua_is_playing()) {
lua_call_update(); lua_call_update();
if (!lua_is_playing()) debug_set_prompt();
} else { } else {
debug_cursor_blink--; debug_cursor_blink--;
if (debug_cursor_blink == 0) { if (debug_cursor_blink == 0) {
debug_cursor_blink = 30; debug_cursor_blink = 30;
debug_text[debug_cursor] = debug_text[debug_cursor]==32 ? 95 : 32; const int pos = cursor_x+cursor_y*screen_width;
char_screen[pos] = char_screen[pos]==32 ? 95 : 32;
} }
loop(); loop();
} }
@@ -214,6 +270,7 @@ int main(int argc,char*argv[]) {
break; break;
case 1: case 1:
case 2: case 2:
case 3:
for (int y=0; y<screen_height; ++y) { for (int y=0; y<screen_height; ++y) {
for (int x=0; x<screen_width; ++x) { for (int x=0; x<screen_width; ++x) {
const uint8_t chr_color = COLSCR(x,y); const uint8_t chr_color = COLSCR(x,y);
@@ -238,7 +295,7 @@ int main(int argc,char*argv[]) {
//for (int i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]]; //for (int i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
SDL_UnlockTexture(mini_bak); 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_SetRenderDrawColor(mini_ren, 255, 0, 0, 0);
SDL_RenderClear(mini_ren); SDL_RenderClear(mini_ren);
SDL_Rect rect = {40, 40, 640, 480}; SDL_Rect rect = {40, 40, 640, 480};
@@ -254,12 +311,10 @@ int main(int argc,char*argv[]) {
void cls(uint8_t value) { void cls(uint8_t value) {
SDL_memset(char_screen, value, screen_width*screen_height); SDL_memset(char_screen, value, screen_width*screen_height);
if (current_mode != 0) SDL_memset(color_screen, current_color, screen_width*screen_height); if (current_mode != 0) SDL_memset(color_screen, current_color, screen_width*screen_height);
if (!lua_is_playing()) { cursor_x = cursor_y = 0;
SDL_memset(debug_text, 32, debug_total_size); //if (!lua_is_playing()) {
debug_cursor = 1; // debug_set_prompt()
debug_prompt = 0; //}
debug_text[debug_prompt] = '>';
}
} }
void ink(uint8_t value) { void ink(uint8_t value) {
@@ -270,8 +325,13 @@ void paper(uint8_t value) {
current_color = (current_color & 0x0f) + (value << 4); 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); current_color = (ink & 0x0f) + (paper << 4);
if (border >= 0) current_border = border & 0xf;
} }
void locate(uint8_t x, uint8_t y) { void locate(uint8_t x, uint8_t y) {
@@ -283,15 +343,22 @@ void print(const char *str, int x, int y) {
if (x >= 0) cursor_x = min(x, screen_width-1); if (x >= 0) cursor_x = min(x, screen_width-1);
if (y >= 0) cursor_y = min(y, screen_height-1); if (y >= 0) cursor_y = min(y, screen_height-1);
int len = SDL_strlen(str); 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; //int offset = x+y*screen_width;
for (int i=0; i < len; ++i) { for (int i=0; i < len; ++i) {
CHRSCR(cursor_x+i, cursor_y) = str[i]; char_screen[pos+i] = str[i];
if (current_mode != 0) COLSCR(cursor_x+i, cursor_y) = current_color; if (current_mode != 0) color_screen[pos+i] = current_color;
//char_screen[offset+i] = str[i]; //char_screen[offset+i] = str[i];
//if (current_mode != 0) color_screen[offset+i] = current_color; //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) { bool btn(uint8_t i) {
@@ -384,46 +451,66 @@ int rnd(int x) {
srand(x); srand(x);
}*/ }*/
char tostr_tmp[256]; char str_tmp[1024];
const char* tostr(float val) { const char* tostr(float val) {
return SDL_itoa(val, tostr_tmp, 10); return SDL_itoa(val, str_tmp, 10);
}
void debug_set_prompt() {
debug_prompt = debug_cursor++;
debug_text[debug_prompt] = '>';
} }
void debug_one_line_up() { void debug_one_line_up() {
for (int i=0; i<debug_total_size-debug_line_size;++i) debug_text[i] = debug_text[i+debug_line_size]; int total = screen_width*screen_height-screen_width;
for (int i=debug_total_size-debug_line_size; i<debug_total_size;++i) debug_text[i] = 32; for (int i=0; i<total;++i) char_screen[i] = char_screen[i+screen_width];
debug_cursor = debug_total_size-debug_line_size; for (int i=total; i<screen_width*screen_height;++i) char_screen[i] = 32;
debug_set_prompt(); cursor_y = screen_height-1;
//debug_set_prompt();
}
void debug_set_prompt() {
if (debug_prompt == cursor_x+cursor_y*screen_width) return;
if (cursor_x>0) { cursor_x=0;cursor_y++;if(cursor_y>=screen_height) debug_one_line_up(); }
char_screen[cursor_x+cursor_y*screen_width] = '>';
cursor_x++;
debug_prompt = cursor_x+cursor_y*screen_width;
} }
void debugchr(const uint8_t chr) { void debugchr(const uint8_t chr) {
int pos = cursor_x+cursor_y*screen_width;
if (chr == 8) { if (chr == 8) {
if (debug_cursor>(debug_prompt+1)) { if (cursor_x>1) {
debug_text[debug_cursor--] = 32; char_screen[pos++] = 32;
debug_text[debug_cursor] = 32; char_screen[pos] = 32;
cursor_x--;
} else {
play("c");
} }
} else { } else {
debug_text[debug_cursor++] = chr; char_screen[pos] = chr;
if (debug_cursor >= debug_total_size) debug_one_line_up(); cursor_x++;
if (cursor_x >= screen_width) {
cursor_x=0; cursor_y++;
if (cursor_y >= screen_height) debug_one_line_up();
}
} }
} }
void debug(const char *str) { void debug(const char *str, const bool newline) {
const int len = SDL_strlen(str); const int len = SDL_strlen(str);
int cursor = cursor_x+cursor_y*screen_width;
for (int i=0; i<len;++i) { for (int i=0; i<len;++i) {
debug_text[debug_cursor++] = str[i]; char_screen[cursor++] = str[i];
if (debug_cursor >= debug_total_size) debug_one_line_up(); if (cursor >= screen_width*screen_height) debug_one_line_up();
} }
debug_cursor = (int(debug_cursor/debug_line_size)+1)*debug_line_size; if (newline) {
if (debug_cursor >= debug_total_size) debug_one_line_up(); cursor_x = 0;
debug_set_prompt(); cursor_y = (cursor/screen_width)+1;
if (cursor_y >= screen_height) debug_one_line_up();
} else {
cursor_x = cursor%screen_width;
cursor_y = cursor/screen_width;
}
//debug_set_prompt();
} }
/*[TODEL]
void pdebug() { void pdebug() {
int i=0; int i=0;
for (int y=0; y<debug_num_lines;++y) { for (int y=0; y<debug_num_lines;++y) {
@@ -433,10 +520,49 @@ void pdebug() {
} }
} }
} }
*/
int cmd_index = 0;
void debug_get_cmd() { void debug_get_cmd() {
debug_text[debug_cursor] = 0; char_screen[cursor_x+cursor_y*screen_width] = 0;
lua_call_cmd(&debug_text[debug_prompt+1]); //char *tmp = (char*)&char_screen[1+cursor_y*screen_width];
char *tmp = (char*)&char_screen[debug_prompt];
cmd_list.push_back(tmp);
char_screen[cursor_x+cursor_y*screen_width] = 32;
cursor_x=0;cursor_y++;if(cursor_y>=screen_height)debug_one_line_up();
cmd_index=0;
const char* cmd = cmd_list[cmd_list.size()-1].c_str();
if (cmd[0]=='r' && cmd[1]=='u' && cmd[2]=='n' && cmd[3]=='\0') {
lua_quit();
reinit();
lua_init(lua_filename);
lua_call_init();
} else if (cmd[0]=='c' && cmd[1]=='o' && cmd[2]=='n' && cmd[3]=='t' && cmd[4]=='\0') {
lua_resume();
} else {
lua_call_cmd(cmd);
debug_set_prompt();
}
}
void get_cmd_by_index() {
if (cmd_list.size() == 0) return;
const char* cmd = cmd_list[cmd_list.size()-cmd_index-1].c_str();
int pos = cursor_x+cursor_y*screen_width;
for (int i=debug_prompt;i<=pos;++i) char_screen[i] = 32;
SDL_memcpy(&char_screen[debug_prompt], cmd, strlen(cmd));
pos = debug_prompt+strlen(cmd);
cursor_x = pos%screen_width;
cursor_y = pos/screen_width;
}
void next_cmd() {
if (cmd_index < cmd_list.size()-1) cmd_index++; else play("c");
get_cmd_by_index();
}
void prev_cmd() {
if (cmd_index > 0) cmd_index--; else play("c");
get_cmd_by_index();
} }
uint8_t ascii(const char *str, uint8_t index) { uint8_t ascii(const char *str, uint8_t index) {
@@ -450,6 +576,12 @@ const char* chr(uint8_t ascii) {
return chr_trans; 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) { 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] = b0;
mem[MEM_CHAR_OFFSET+index*8+1] = b1; mem[MEM_CHAR_OFFSET+index*8+1] = b1;
@@ -480,19 +612,27 @@ void memcpy(uint16_t dst, uint16_t src, uint16_t size) {
void sound(float freq, uint32_t len) { void sound(float freq, uint32_t len) {
// [TODO] // [TODO]
audio_len = len*44.1f; audio_len = len*44.1f;
audio_freq = 44100.0f/freq/2.0f; audio_freq = 22050.0f/freq/2.0f;
sounding = true; audio_state = AUDIO_SOUND;
} }
void nosound() { void nosound() {
//SDL_PauseAudioDevice(mini_audio_device, 1); //SDL_PauseAudioDevice(mini_audio_device, 1);
audio_len = 0; 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) { void setmode(const uint8_t mode) {
current_mode = mode; current_mode = mode;
reinit(); reinit();
cls();
} }
void load(const char* str) { void load(const char* str) {
@@ -511,3 +651,22 @@ void filein(const char* str, uint16_t addr, uint16_t size) {
fread(&mem[addr], size, 1, f); fread(&mem[addr], size, 1, f);
fclose(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;
}

37
ascii.h
View File

@@ -110,15 +110,37 @@
#define KEY_RALT 230 #define KEY_RALT 230
#define KEY_RGUI 231 #define KEY_RGUI 231
#define COLOR_BLACK 0
#define COLOR_BLUE 1
#define COLOR_GREEN 2
#define COLOR_CYAN 3
#define COLOR_RED 4
#define COLOR_MAGENTA 5
#define COLOR_BROWN 6
#define COLOR_LIGHT_GRAY 7
#define COLOR_DARK_GRAY 8
#define COLOR_LIGHT_BLUE 9
#define COLOR_LIGHT_GREEN 10
#define COLOR_LIGHT_CYAN 11
#define COLOR_LIGHT_RED 12
#define COLOR_LIGHT_MAGENTA 13
#define COLOR_YELLOW 14
#define COLOR_WHITE 15
void loop(); void loop();
void execute_run();
const char* get_filename();
void cls(uint8_t value=32); void cls(uint8_t value=32);
void ink(uint8_t value); // global::ink void ink(uint8_t value); // global::ink
void paper(uint8_t value); // global::paper 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 locate(uint8_t x, uint8_t y); // global::cursorx, global::cursory
void print(const char *str, int x = -1, int y = -1); void print(const char *str, int x = -1, int y = -1);
void crlf();
bool btn(uint8_t i); bool btn(uint8_t i);
bool btnp(uint8_t i); bool btnp(uint8_t i);
@@ -156,12 +178,15 @@ int rnd(int x);
const char* tostr(float val); const char* tostr(float val);
void debugchr(const uint8_t chr); void debugchr(const uint8_t chr);
void debug(const char *str); void debug(const char *str, const bool newline=true);
void pdebug(); //void pdebug();
void debug_get_cmd(); void debug_get_cmd();
void next_cmd();
void prev_cmd();
uint8_t ascii(const char *str, uint8_t index); uint8_t ascii(const char *str, uint8_t index);
const char* chr(uint8_t ascii); 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); 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); uint8_t peek(uint16_t addr);
@@ -170,9 +195,13 @@ void memcpy(uint16_t dst, uint16_t src, uint16_t size);
void sound(float freq, uint32_t len); void sound(float freq, uint32_t len);
void nosound(); 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 load(const char* str);
void fileout(const char* str, uint16_t addr, uint16_t size); void fileout(const char* str, uint16_t addr, uint16_t size);
void filein(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() function init()
setmode(0) setmode(0)
cls()
play("o4v5l1crcl4dcferl1crcl4dcgfr")
end end
function update() 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 end

205
lua.cpp
View File

@@ -2,6 +2,86 @@
#include "lua/lua.hpp" #include "lua/lua.hpp"
#include "ascii.h" #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" { extern "C" {
static int cpp_cls(lua_State *L) { static int cpp_cls(lua_State *L) {
uint8_t color = luaL_optinteger(L, 1, 32); uint8_t color = luaL_optinteger(L, 1, 32);
@@ -21,10 +101,21 @@ extern "C" {
return 0; 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) { static int cpp_color(lua_State *L) {
uint8_t ink = luaL_checkinteger(L, 1); uint8_t ink = luaL_checkinteger(L, 1);
uint8_t paper = luaL_checkinteger(L, 2); uint8_t paper = luaL_checkinteger(L, 2);
if (lua_gettop(L) > 2) {
uint8_t border = luaL_checkinteger(L, 3);
color(ink, paper, border);
} else {
color(ink, paper); color(ink, paper);
}
return 0; return 0;
} }
@@ -43,6 +134,11 @@ extern "C" {
return 0; return 0;
} }
static int cpp_crlf(lua_State *L) {
crlf();
return 0;
}
static int cpp_btn(lua_State *L) { static int cpp_btn(lua_State *L) {
uint8_t i = luaL_checkinteger(L, 1); uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, btn(i)); lua_pushboolean(L, btn(i));
@@ -152,9 +248,28 @@ extern "C" {
return 0; return 0;
} }
static int cpp_tostr(lua_State *L) { static int cpp_tostr(lua_State *L) {
float val = luaL_checknumber(L, 1); ts_index=0;
lua_pushstring(L, tostr(val)); value_to_str(L, 1); tempstr[ts_index] = '\0';
lua_pushstring(L, tempstr);
return 1; 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) { static int cpp_ascii(lua_State *L) {
const char* str = luaL_checkstring(L, 1); const char* str = luaL_checkstring(L, 1);
@@ -172,6 +287,13 @@ extern "C" {
lua_pushinteger(L, strlen(str)); lua_pushinteger(L, strlen(str));
return 1; 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) { static int cpp_setchar(lua_State *L) {
int index = luaL_checkinteger(L, 1); int index = luaL_checkinteger(L, 1);
@@ -220,9 +342,15 @@ extern "C" {
return 0; 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) { static int cpp_setmode(lua_State *L) {
int val = luaL_checkinteger(L, 1); int val = luaL_checkinteger(L, 1);
setmode(val); setmode(mid(0,val,3));
return 0; return 0;
} }
@@ -253,6 +381,17 @@ extern "C" {
filein(str, addr, size); filein(str, addr, size);
return 0; 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 #define STATE_STOPPED 0
@@ -261,35 +400,33 @@ extern "C" {
lua_State *L; lua_State *L;
uint8_t lua_state = STATE_STOPPED; uint8_t lua_state = STATE_STOPPED;
bool init_exists = false; //bool init_exists = false;
bool update_exists = false; //bool update_exists = false;
bool lua_is_playing() { bool lua_is_playing() {
return lua_state == STATE_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) { void lua_init(const char* filename, const bool start_playing) {
if (lua_state != STATE_STOPPED) lua_quit(); if (lua_state != STATE_STOPPED) lua_quit();
L = luaL_newstate(); L = luaL_newstate();
init_exists = update_exists = false; //init_exists = update_exists = false;
bool file_loaded = true; bool file_loaded = true;
if (filename == NULL) { if (filename == NULL) {
if (luaL_loadstring(L, boot)) { if (luaL_loadstring(L, boot)) {
debug("BOOT ERROR"); debug("BOOT ERROR:", false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
setmode(0);
file_loaded = false; file_loaded = false;
} }
} else { } else {
if (luaL_loadfile(L, filename)) { if (luaL_loadfile(L, filename)) {
debug("ERROR LOADING GAME"); debug("ERROR LOADING GAME:",false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
setmode(0);
file_loaded = false; file_loaded = false;
} }
} }
@@ -297,10 +434,12 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_cls); lua_setglobal(L, "cls"); lua_pushcfunction(L,cpp_cls); lua_setglobal(L, "cls");
lua_pushcfunction(L,cpp_ink); lua_setglobal(L, "ink"); lua_pushcfunction(L,cpp_ink); lua_setglobal(L, "ink");
lua_pushcfunction(L,cpp_paper); lua_setglobal(L, "paper"); 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_color); lua_setglobal(L, "color");
lua_pushcfunction(L,cpp_locate); lua_setglobal(L, "locate"); lua_pushcfunction(L,cpp_locate); lua_setglobal(L, "locate");
lua_pushcfunction(L,cpp_print); lua_setglobal(L, "print"); 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_btn); lua_setglobal(L, "btn");
lua_pushcfunction(L,cpp_btnp); lua_setglobal(L, "btnp"); lua_pushcfunction(L,cpp_btnp); lua_setglobal(L, "btnp");
@@ -328,6 +467,7 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_ascii); lua_setglobal(L, "ascii"); lua_pushcfunction(L,cpp_ascii); lua_setglobal(L, "ascii");
lua_pushcfunction(L,cpp_chr); lua_setglobal(L, "chr"); lua_pushcfunction(L,cpp_chr); lua_setglobal(L, "chr");
lua_pushcfunction(L,cpp_strlen); lua_setglobal(L, "strlen"); 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_setchar); lua_setglobal(L, "setchar");
lua_pushcfunction(L,cpp_peek); lua_setglobal(L, "peek"); lua_pushcfunction(L,cpp_peek); lua_setglobal(L, "peek");
@@ -335,12 +475,15 @@ void lua_init(const char* filename, const bool start_playing) {
lua_pushcfunction(L,cpp_memcpy); lua_setglobal(L, "memcpy"); lua_pushcfunction(L,cpp_memcpy); lua_setglobal(L, "memcpy");
lua_pushcfunction(L,cpp_sound); lua_setglobal(L, "sound"); lua_pushcfunction(L,cpp_sound); lua_setglobal(L, "sound");
lua_pushcfunction(L,cpp_nosound); lua_setglobal(L, "nosound"); 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_setmode); lua_setglobal(L, "setmode");
lua_pushcfunction(L,cpp_load); lua_setglobal(L, "load"); lua_pushcfunction(L,cpp_load); lua_setglobal(L, "load");
lua_pushcfunction(L,cpp_log); lua_setglobal(L, "log"); lua_pushcfunction(L,cpp_log); lua_setglobal(L, "log");
lua_pushcfunction(L,cpp_fileout); lua_setglobal(L, "fileout"); lua_pushcfunction(L,cpp_fileout); lua_setglobal(L, "fileout");
lua_pushcfunction(L,cpp_filein); lua_setglobal(L, "filein"); 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, 0); lua_setglobal(L, "KEY_UNKNOWN");
lua_pushinteger(L, 4); lua_setglobal(L, "KEY_A"); lua_pushinteger(L, 4); lua_setglobal(L, "KEY_A");
@@ -470,13 +613,13 @@ void lua_init(const char* filename, const bool start_playing) {
if (!file_loaded) return; if (!file_loaded) return;
if (lua_pcall(L,0, LUA_MULTRET, 0)) { if (lua_pcall(L,0, LUA_MULTRET, 0)) {
debug("RUNTIME ERROR"); debug("RUNTIME ERROR:", false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
setmode(0);
return; return;
} }
/*
lua_getglobal(L, "init"); lua_getglobal(L, "init");
if (lua_isfunction(L,-1)) init_exists = true; if (lua_isfunction(L,-1)) init_exists = true;
lua_pop(L,1); lua_pop(L,1);
@@ -484,42 +627,56 @@ void lua_init(const char* filename, const bool start_playing) {
lua_getglobal(L, "update"); lua_getglobal(L, "update");
if (lua_isfunction(L,-1)) update_exists = true; if (lua_isfunction(L,-1)) update_exists = true;
lua_pop(L,1); lua_pop(L,1);
*/
lua_state = start_playing ? STATE_PLAYING : STATE_PAUSED; lua_state = start_playing ? STATE_PLAYING : STATE_PAUSED;
} }
void lua_call_cmd(const char* str) { void lua_call_cmd(const char* str) {
if (luaL_dostring(L, str)) { if (str[0]=='?') {
debug(" "); const int size = strlen(str)+14;
debug("ERROR"); char* cmd = (char*)malloc(size);
memcpy(cmd, "print(tostr(", 12);
memcpy(&cmd[12], &str[1], strlen(str)-1);
cmd[size-1]='\0';
cmd[size-3]=cmd[size-2]=')';
if (luaL_dostring(L, cmd)) {
debug("ERROR:",false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
} }
debug(" "); } else {
if (luaL_dostring(L, str)) {
debug("ERROR:",false);
debug(lua_tostring(L, -1));
lua_pop(L,1);
}
}
} }
void lua_call_init() { void lua_call_init() {
if (!init_exists) return;
lua_getglobal(L, "init"); lua_getglobal(L, "init");
if (lua_isfunction(L,-1)) {
if (lua_pcall(L, 0, 0, 0)) { if (lua_pcall(L, 0, 0, 0)) {
debug("RUNTIME ERROR"); debug("RUNTIME ERROR:",false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
setmode(0);
lua_state = STATE_STOPPED; lua_state = STATE_STOPPED;
} }
}
} }
void lua_call_update() { void lua_call_update() {
if (!update_exists) return;
lua_getglobal(L, "update"); lua_getglobal(L, "update");
if (lua_isfunction(L,-1)) {
if (lua_pcall(L, 0, 0, 0)) { if (lua_pcall(L, 0, 0, 0)) {
debug("RUNTIME ERROR"); debug("RUNTIME ERROR:",false);
debug(lua_tostring(L, -1)); debug(lua_tostring(L, -1));
lua_pop(L,1); lua_pop(L,1);
setmode(0);
lua_state = STATE_STOPPED; lua_state = STATE_STOPPED;
} }
} else {
lua_state = STATE_PAUSED;
}
} }
void lua_quit() { void lua_quit() {

451
main.cpp
View File

@@ -1,55 +1,428 @@
#include "ascii.h" #include "ascii.h"
#include <stdio.h>
#include <string>
#include <list>
std::list<std::string> code;
int current_editor = 0; int current_editor = 0;
void do_terminal() { void init_terminal();
SDL_Keymod mods = SDL_GetModState(); void do_terminal();
const uint8_t key = whichbtn();
if (key != KEY_UNKNOWN) { void init_code_editor();
if (key < 30) { void do_code_editor();
if ((mods & KMOD_SHIFT) || (mods & KMOD_CAPS)) { void save_code();
debugchr(key+61);
} else {
debugchr(key+93);
}
}
//else if (key < 39) debugchr(key+19);
else if (key == KEY_0) { if (mods & KMOD_SHIFT) { debugchr('='); } else { debugchr('0'); } }
else if (key == KEY_1) { if (mods & KMOD_SHIFT) { debugchr('!'); } else if (mods & KMOD_RALT) { debugchr('|'); } else { debugchr('1'); } }
else if (key == KEY_2) { if (mods & KMOD_SHIFT) { debugchr('"'); } else if (mods & KMOD_RALT) { debugchr('@'); } else { debugchr('2'); } }
else if (key == KEY_3) { if (mods & KMOD_SHIFT) { debugchr(144); } else if (mods & KMOD_RALT) { debugchr('#'); } else { debugchr('3'); } }
else if (key == KEY_4) { if (mods & KMOD_SHIFT) { debugchr('$'); } else if (mods & KMOD_RALT) { debugchr('~'); } else { debugchr('4'); } }
else if (key == KEY_5) { if (mods & KMOD_SHIFT) { debugchr('%'); } else if (mods & KMOD_RALT) { debugchr(180); } else { debugchr('5'); } }
else if (key == KEY_6) { if (mods & KMOD_SHIFT) { debugchr('&'); } else if (mods & KMOD_RALT) { debugchr(173); } else { debugchr('6'); } }
else if (key == KEY_7) { if (mods & KMOD_SHIFT) { debugchr('/'); } else { debugchr('7'); } }
else if (key == KEY_8) { if (mods & KMOD_SHIFT) { debugchr('('); } else { debugchr('8'); } }
else if (key == KEY_9) { if (mods & KMOD_SHIFT) { debugchr(')'); } else { debugchr('9'); } }
else if (key == KEY_RETURN) debug_get_cmd();
else if (key == KEY_SPACE) debugchr(32);
else if (key == KEY_BACKSPACE) debugchr(8);
else if (key == KEY_MINUS) { if (mods & KMOD_SHIFT) { debugchr('?'); } else { debugchr('\''); } }
else if (key == KEY_EQUALS) { if (mods & KMOD_SHIFT) { debugchr(174); } else { debugchr(175); } }
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('-'); } }
}
//cls(0);
pdebug();
}
void loop() { void loop() {
do_terminal();
/*
if (btnp(KEY_TAB)) { if (btnp(KEY_TAB)) {
current_editor = (++current_editor)%5; current_editor = (++current_editor)%2;
switch(current_editor) {
case 0:
init_terminal();
break;
case 1:
init_code_editor();
break;
}
} }
switch(current_editor) { switch(current_editor) {
case 0: case 0:
do_terminal(); do_terminal();
break; break;
case 1: case 1:
do_sprite_editor(); do_code_editor();
break; break;
} }
*/ }
void execute_run() {
if (current_editor == 1) save_code();
}
uint8_t get_char(uint8_t key) {
SDL_Keymod mods = SDL_GetModState();
if (key != KEY_UNKNOWN) {
if (key < 30) {
if ((mods & KMOD_SHIFT) || (mods & KMOD_CAPS)) {
return key+61;
} else {
return key+93;
}
}
else if (key == KEY_0) { if (mods & KMOD_SHIFT) { return '='; } else { return '0'; } }
else if (key == KEY_1) { if (mods & KMOD_SHIFT) { return '!'; } else if (mods & KMOD_RALT) { return '|'; } else { return '1'; } }
else if (key == KEY_2) { if (mods & KMOD_SHIFT) { return '"'; } else if (mods & KMOD_RALT) { return '@'; } else { return '2'; } }
else if (key == KEY_3) { if (mods & KMOD_SHIFT) { return 144; } else if (mods & KMOD_RALT) { return '#'; } else { return '3'; } }
else if (key == KEY_4) { if (mods & KMOD_SHIFT) { return '$'; } else if (mods & KMOD_RALT) { return '~'; } else { return '4'; } }
else if (key == KEY_5) { if (mods & KMOD_SHIFT) { return '%'; } else if (mods & KMOD_RALT) { return 180; } else { return '5'; } }
else if (key == KEY_6) { if (mods & KMOD_SHIFT) { return '&'; } else if (mods & KMOD_RALT) { return 173; } else { return '6'; } }
else if (key == KEY_7) { if (mods & KMOD_SHIFT) { return '/'; } else { return '7'; } }
else if (key == KEY_8) { if (mods & KMOD_SHIFT) { return '('; } else { return '8'; } }
else if (key == KEY_9) { if (mods & KMOD_SHIFT) { return ')'; } else { return '9'; } }
else if (key == KEY_SPACE) return 32;
else if (key == KEY_MINUS) { if (mods & KMOD_SHIFT) { return '?'; } else { return '\''; } }
else if (key == KEY_EQUALS) { if (mods & KMOD_SHIFT) { return 174; } else { return 175; } }
else if (key == KEY_COMMA) { if (mods & KMOD_SHIFT) { return ';'; } else { return ','; } }
else if (key == KEY_PERIOD) { if (mods & KMOD_SHIFT) { return ':'; } else { return '.'; } }
else if (key == KEY_SLASH) { if (mods & KMOD_SHIFT) { return '_'; } else { return '-'; } }
else if (key == KEY_LEFTBRACKET) { if (mods & KMOD_SHIFT) { return 160; } else if (mods & KMOD_RALT) { return '['; } else { return 96; } }
else if (key == KEY_RIGHTBRACKET) { if (mods & KMOD_SHIFT) { return '*'; } else if (mods & KMOD_RALT) { return ']'; } else { return '+'; } }
else if (key == KEY_APOSTROPHE) { if (mods & KMOD_SHIFT) { return 162; } else if (mods & KMOD_RALT) { return '{'; } else { return 161; } }
else if (key == KEY_BACKSLASH) { if (mods & KMOD_SHIFT) { return 'C'; } else if (mods & KMOD_RALT) { return '}'; } else { return 'c'; } }
else if (key == KEY_GRAVE) { if (mods & KMOD_SHIFT) { return '>'; } else { return '<'; } }
else if (key == KEY_NONUSBACKSLASH) { if (mods & KMOD_SHIFT) { return 164; } else if (mods & KMOD_RALT) { return '\\'; } else { return 163; } }
else return 0;
} else {
return 0;
}
}
void init_terminal() {
setmode(0);
cls();
}
void do_terminal() {
//SDL_Keymod mods = SDL_GetModState();
const uint8_t key = whichbtn();
if (key != KEY_UNKNOWN) {
if (key == KEY_RETURN or key == KEY_KP_ENTER) debug_get_cmd();
else if (key == KEY_UP) next_cmd();
else if (key == KEY_DOWN) prev_cmd();
else if (key == KEY_BACKSPACE) debugchr(8);
else {
uint8_t chr = get_char(key);
if (chr != 0) debugchr(chr);
}
}
}
void save_code() {
const char* file = get_filename();
FILE *f = fopen(file, "w");
for (std::list<std::string>::iterator it = code.begin(); it != code.end(); it++) {
fprintf(f, "%s\n", (*it).c_str());
}
fclose(f);
}
void load_code() {
const char* file = get_filename();
FILE *f = fopen(file, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
char *buffer = (char*)malloc(fsize + 1);
fread(buffer, 1, fsize, f);
fclose(f);
buffer[fsize] = 0;
int start = 0;
for (int pos=0;pos<fsize;++pos) {
if (buffer[pos] == '\n') {
buffer[pos]='\0';
code.push_back(&buffer[start]);
start=pos+1;
} else if (buffer[pos] == '\r') {
buffer[pos]='\0';
code.push_back(&buffer[start]);
start=pos+1;
if (buffer[start] == '\n') {pos++; start++;}
}
}
free(buffer);
}
std::list<std::string>::iterator ls[28];
static int col = 0;
static int line = 0;
bool cursor_inverted = false;
int blink_wait = 30;
#define PARSER_NOTHING 0
#define PARSER_NUMBER 1
#define PARSER_IDENTIFIER 2
#define PARSER_STRING 3
#define PARSER_COMMENT 4
#define PARSER_FUNCTION 5
uint16_t parser_offset = 0;
uint8_t parser_pos = 0;
uint8_t parser_start=0;
void parser_setup(uint16_t address) {
parser_offset = address;
parser_pos = 0;
parser_start = 0;
}
const uint8_t parser_get_char(uint8_t offset=0) {
if ((parser_pos+offset) >= 80) return 0;
return peek(parser_offset+parser_pos+offset);
}
char alpha[80] = "";
uint8_t alpha_pos = 0;
void parser_next(const bool keep=false) {
if (keep) { alpha[alpha_pos++] = parser_get_char(); alpha[alpha_pos]=0; } else { alpha[0]=alpha_pos=0; }
if (parser_pos < 80) parser_pos++;
}
#define ISZERO (parser_get_char()=='0')
#define ISX (parser_get_char()=='z' || parser_get_char()=='Z')
#define ISDIGIT (parser_get_char()>='0' && parser_get_char() <='9')
#define WILLBEDIGIT (parser_get_char(1)>='0' && parser_get_char(1) <='9')
#define ISPOINT (parser_get_char()=='.')
#define ISALPHA (parser_get_char()>='_' || (parser_get_char()>='a' && parser_get_char()<='z') || (parser_get_char()>='A' && parser_get_char()<='Z'))
#define ISQUOTES (parser_get_char()=='"' || parser_get_char()=='\'')
#define ISMINUS (parser_get_char()=='-')
#define WILLBEMINUS (parser_get_char(1)=='-')
#define ISPAREN (parser_get_char()=='(')
#define ENDED (parser_get_char()==0)
const char* keywords[] = { "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while" };
const bool is_keyword() {
for (int i=0;i<22;++i) if (strcmp(alpha, keywords[i]) == 0) return true;
return false;
}
void parser_do_color(uint8_t type) {
uint8_t color = COLOR_WHITE;
switch (type) {
case PARSER_NUMBER: color = COLOR_LIGHT_GREEN; break;
case PARSER_COMMENT: color = COLOR_LIGHT_GRAY; break;
case PARSER_STRING: color = COLOR_RED; break;
case PARSER_IDENTIFIER: if (is_keyword()) color = COLOR_MAGENTA; break;
case PARSER_FUNCTION: color = COLOR_YELLOW; break;
};
color = (color&0x0f)+(0x10);
for (int i=parser_start;i<parser_pos;++i) poke(0x1200+parser_offset+i, color);
parser_start = parser_pos;
}
void refresh_line_color(uint8_t line) {
parser_setup(80*(line+1));
while (!ENDED) {
uint8_t result = PARSER_NOTHING;
if (ISZERO) {
result=PARSER_NUMBER; parser_next();
if (ISX) {
if (WILLBEDIGIT) {
parser_next();
while (ISDIGIT) parser_next();
}
} else if (ISDIGIT) {
while (ISDIGIT) parser_next();
if (ISPOINT) {
parser_next();
while (ISDIGIT) parser_next();
}
} else if (ISPOINT) {
parser_next();
while (ISDIGIT) parser_next();
}
} else if (ISDIGIT) {
result = PARSER_NUMBER;
while (ISDIGIT) parser_next();
if (ISPOINT) {
parser_next();
while (ISDIGIT) parser_next();
}
} else if (ISALPHA) {
result = PARSER_IDENTIFIER;
while (ISALPHA || ISDIGIT) parser_next(true);
if (ISPAREN) result = PARSER_FUNCTION;
} else if (ISQUOTES) {
result = PARSER_STRING; parser_next();
while (!ISQUOTES && !ENDED) parser_next();
parser_next();
} else if (ISMINUS) {
if (WILLBEMINUS) {
result = PARSER_COMMENT;
while (!ENDED) parser_next();
}
}
if (result == PARSER_NOTHING) parser_next();
parser_do_color(result);
}
}
void refresh_color_highlight() {
cursor_inverted = false;
for (int i=0;i<28;++i) refresh_line_color(i);
}
void refresh_code_editor() {
color(COLOR_WHITE, COLOR_BLUE);
cls();
color(COLOR_BLACK, COLOR_LIGHT_GRAY);
print(" File Edit Run ",0,0);
print(" ",0,29);
color(COLOR_WHITE, COLOR_BLUE);
std::list<std::string>::iterator it = code.begin();
int i=0;
while (it != code.end() && i<28) {
ls[i] = it;
print((*it).c_str(), 0, i+1);
++i; ++it;
}
refresh_color_highlight();
}
void init_code_editor() {
setmode(3);
code.clear();
load_code();
refresh_code_editor();
}
std::string get_current_line() {
return *ls[line];
}
void invert_cursor() {
cursor_inverted = !cursor_inverted;
uint16_t pos = 0x1200 + col + (line+1)*80;
uint8_t col = peek(pos);
poke(pos, ((col >> 4) & 0x0f) + ((col << 4) & 0xf0) );
}
void move_cursor_up() {
if (line > 0) {
if (cursor_inverted) invert_cursor();
line--;
if (get_current_line().size() < col) col = get_current_line().size();
blink_wait=1;
}
}
void move_cursor_down() {
if (line < code.size()-1) {
if (cursor_inverted) invert_cursor();
line++;
if (get_current_line().size() < col) col = get_current_line().size();
blink_wait=1;
}
}
void move_cursor_right() {
if ( col < get_current_line().size() ) {
if (cursor_inverted) invert_cursor();
col++;
blink_wait=1;
} else {
if (line < code.size()-1) {
col = 0;
move_cursor_down();
}
}
}
void move_cursor_left() {
if (col > 0) {
if (cursor_inverted) invert_cursor();
col--;
blink_wait=1;
} else {
if (line > 0) {
move_cursor_up();
col = get_current_line().size();
}
}
}
void move_line_end() {
if (cursor_inverted) invert_cursor();
col = get_current_line().size();
blink_wait=1;
}
void move_line_home() {
if (cursor_inverted) invert_cursor();
col = 0;
blink_wait=1;
}
void split_line() {
std::string str = get_current_line();
*ls[line] = str.substr(col);
std::list<std::string>::iterator newline = ls[line]++;
code.insert(newline, str.substr(0, col));
if (cursor_inverted) invert_cursor();
line++; col=0;
blink_wait=1;
refresh_code_editor();
}
void join_lines() {
if (cursor_inverted) invert_cursor();
std::string str = get_current_line();
//std::list<std::string>::iterator prevline = ls[line]--;
code.erase(ls[line]);
line--;
const int line_size = (*ls[line]).size();
*ls[line] += str;
col = line_size;
blink_wait=1;
refresh_code_editor();
}
void delete_char() {
if (col == 0) {
if (line > 0) join_lines();
} else {
if (cursor_inverted) invert_cursor();
std::string str = get_current_line();
std::string a = str.substr(0,col-1);
std::string b = str.substr(col);
*ls[line] = a+b;
col--;
blink_wait=1;
refresh_code_editor();
}
}
void supr_char() {
if ((col == (*ls[line]).size()) && (line == code.size()-1)) return;
move_cursor_right();
delete_char();
}
void add_char(uint8_t chr) {
std::string str = get_current_line();
std::string a = str.substr(0,col);
std::string b = str.substr(col);
std::string c = " "; c[0] = chr;
*ls[line] = a+c+b;
col++;
blink_wait=1;
refresh_code_editor();
}
void do_code_editor() {
const uint8_t key = whichbtn();
if (key != KEY_UNKNOWN) {
if (key == KEY_RETURN or key == KEY_KP_ENTER) {
split_line();
}
else if (key == KEY_UP) move_cursor_up();
else if (key == KEY_DOWN) move_cursor_down();
else if (key == KEY_LEFT) move_cursor_left();
else if (key == KEY_RIGHT) move_cursor_right();
else if (key == KEY_BACKSPACE) delete_char();
else if (key == KEY_DELETE) supr_char();
else if (key == KEY_END) move_line_end();
else if (key == KEY_HOME) move_line_home();
else {
uint8_t chr = get_char(key);
if (chr != 0) add_char(chr);
}
}
blink_wait--;
if (blink_wait == 0) {
blink_wait = 30;
invert_cursor();
}
} }

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);

38
tools/defender.lua Normal file
View File

@@ -0,0 +1,38 @@
function init()
setmode(1)
mountains = {}
local val = 2
for i=0,99 do
val = mid(1,val+rnd(3)-1,4)
mountains[i] = val
end
ox=0
end
function update()
cls()
draw_mountains()
if btn(KEY_RIGHT) then ox=(ox+1)%100 end
if btn(KEY_LEFT) then ox=(ox-1)%100 end
end
function draw_mountains()
color(COLOR_RED,COLOR_BLACK)
for i=0,39 do
local x=(ox+i)%100
for j=29-mountains[x],29 do
local chr="\143"
if j==29-mountains[x] then
if mountains[(x+1)%100] > mountains[x] then
print("\214",i,j-1) --chr="\214"
elseif mountains[(x+1)%100] < mountains[x] then
chr="\215"
end
end
print(chr,i,j)
end
end
end

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