453 lines
12 KiB
C
453 lines
12 KiB
C
|
|
#define logcu(fmt, args ...) logu(LOG_CON, fmt, args)
|
|
#define logci(fmt, args ...) logi(LOG_CON, fmt, args)
|
|
#define logcw(fmt, args ...) logw(LOG_CON, fmt, args)
|
|
#define logce(fmt, args ...) loge(LOG_CON, fmt, args)
|
|
|
|
int str_tokenize(char *arg, char **args, const char *str) {
|
|
// if(str[0] == 0) {
|
|
// return 0;
|
|
// }
|
|
int pos = 0;
|
|
int apos = 0;
|
|
int argc = 0;
|
|
int last = 0;
|
|
byte space = 1;
|
|
byte quote = 0;
|
|
byte escape = 0;
|
|
char c;
|
|
while(c = str[pos++]) {
|
|
if(escape) {
|
|
escape = 0;
|
|
switch(c) {
|
|
case '\\':
|
|
case ' ':
|
|
case '"':
|
|
arg[apos++] = c;
|
|
break;
|
|
default:
|
|
logce(STR_PARSER_ESC_UNKNOWN, pos, c);
|
|
return 0;
|
|
}
|
|
}
|
|
else if(c == '\\') {
|
|
space = 0;
|
|
escape = 1;
|
|
}
|
|
else if(c == '"') {
|
|
space = 0;
|
|
quote = !quote;
|
|
last = pos;
|
|
}
|
|
else if(c == ' ' && !quote) {
|
|
if(!space) {
|
|
args[argc++] = arg;
|
|
arg[apos++] = 0;
|
|
arg += apos;
|
|
apos = 0;
|
|
}
|
|
space = 1;
|
|
}
|
|
else {
|
|
space = 0;
|
|
arg[apos++] = c;
|
|
}
|
|
}
|
|
if(escape) {
|
|
logce(STR_PARSER_ESC_SHORT, pos);
|
|
return 0;
|
|
}
|
|
if(quote) {
|
|
logce(STR_PARSER_NO_QUOTE, last);
|
|
return 0;
|
|
}
|
|
if(!space) {
|
|
args[argc++] = arg;
|
|
arg[apos] = 0;
|
|
}
|
|
return argc;
|
|
}
|
|
|
|
ccmd_t *con_get(const char *key) {
|
|
return (ccmd_t*)smap_get(&sys.ccmd_map, key);
|
|
}
|
|
|
|
void con_exec(const char *line) {
|
|
char str[64];
|
|
int argc;
|
|
char **argv;
|
|
cvar_t *cv;
|
|
ccmd_t *cmd;
|
|
if(!(argc = str_tokenize(sys.con_tok, sys.con_arg, line)))
|
|
return;
|
|
argv = sys.con_arg;
|
|
cv = cvar_get(argv[0]);
|
|
if(cv && argc == 1) {
|
|
cvar_format(cv, str);
|
|
logcu("%s = %s", cv->name, str);
|
|
return;
|
|
}
|
|
else if(cv && argc == 2) {
|
|
if(cv->readonly) {
|
|
logce(STR_CVAR_READONLY, cv->name);
|
|
}
|
|
else if(cvar_set(cv, argv[1], 0)) {
|
|
cvar_format(cv, str);
|
|
logcu("%s = %s", cv->name, str);
|
|
}
|
|
else {
|
|
logce(STR_CVAR_INVALID, cv->name, argv[1]);
|
|
}
|
|
return;
|
|
}
|
|
else if(cv) {
|
|
logce(STR_CVAR_MOREARGS, argc);
|
|
return;
|
|
}
|
|
cmd = con_get(argv[0]);
|
|
if(!cmd) {
|
|
logce(STR_CVAR_CCMD_UNKNOWN, argv[0]);
|
|
return;
|
|
}
|
|
if(--argc < cmd->min) {
|
|
logce(STR_CCMD_LESSARGS, argv[0], cmd->min, argc);
|
|
return;
|
|
}
|
|
else if(argc > cmd->max) {
|
|
logce(STR_CCMD_MOREARGS, argv[0], cmd->max, argc);
|
|
return;
|
|
}
|
|
logcu("# %s", line);
|
|
cmd->func(cmd, (const char **)&argv[1], argc);
|
|
}
|
|
|
|
void con_reset() {
|
|
sys.log_len = sprintf(sys.con_buf, COL_NEON "*** " SYS_PROGRAM_FULL " ***");
|
|
// for(int z = 0; z < sys.con_size; z++) {
|
|
// sys.con_msgs[z].message = NULL;
|
|
// }
|
|
// sys.con_pos = 0;
|
|
}
|
|
|
|
ccmd_t *con_add(const char *name, const char *args, ccmd_func *func, ushort min, ushort max) {
|
|
ccmd_t *cmd = &sys.ccmds[sys.n_ccmds];
|
|
cmd->func = func;
|
|
cmd->args = args;
|
|
cmd->min = min;
|
|
cmd->max = max;
|
|
cmd->id = sys.n_ccmds;
|
|
cmd->name = name;
|
|
sys.n_ccmds += 1;
|
|
return cmd;
|
|
}
|
|
|
|
void con_fmt_cvar(cvar_t *cv, char *str) {
|
|
int pos;
|
|
if(cv->type == CVAR_ENUM) {
|
|
pos = sprintf(str, "%s "COL_DGRAY"["COL_GRAY"D "COL_CRIMSON"%s"COL_DGRAY"] ["COL_LGRAY, ((const char**)cv->aux_data)[cv->value], ((const char**)cv->aux_data)[cv->def]);
|
|
for(int z = 0; z < cv->max; z++) {
|
|
pos += sprintf(str+pos, z ? ", %s" : "%s", ((const char**)cv->aux_data)[z]);
|
|
}
|
|
pos += sprintf(str+pos, COL_DGRAY"]");
|
|
}
|
|
else {
|
|
cvar_fmt[cv->type](str, cv->value);
|
|
pos = strlen(str);
|
|
pos += sprintf(str+pos, " "COL_DGRAY"["COL_GRAY"D "COL_CRIMSON);
|
|
cvar_fmt[cv->type](str+pos, cv->def);
|
|
pos += strlen(str+pos);
|
|
pos += sprintf(str+pos, COL_DGRAY"]");
|
|
if(cv->type == CVAR_INT)
|
|
pos += sprintf(str+pos, " ["COL_LGRAY"%d .. %d"COL_DGRAY"]", cv->min, cv->max);
|
|
else if(cv->type == CVAR_FLOAT)
|
|
pos += sprintf(str+pos, " ["COL_LGRAY"%.3f .. %.3f"COL_DGRAY"]", cvar_itf(cv->min), cvar_itf(cv->max));
|
|
}
|
|
logcu("%s "COL_NEON"%s "COL_DGRAY"[%s"COL_DGRAY"]"COL_GRAY" = "COL_WHITE"%s%s", cvar_types[cv->type], cv->name, cvar_categories[cv->category], str, cv->readonly ? " "COL_DGRAY"["COL_RED"RO"COL_DGRAY"]" : "");
|
|
}
|
|
|
|
void con_cmd_cvar(ccmd_t *cmd, const char **argv, int argc) {
|
|
cvar_t *cv;
|
|
char fmt[512];
|
|
if(argc) {
|
|
for(int z = 0; z < argc; z++) {
|
|
cv = cvar_get(argv[z]);
|
|
if(!cv) {
|
|
logce(STR_CVAR_UNKNOWN, argv[z]);
|
|
continue;
|
|
}
|
|
con_fmt_cvar(cv, fmt);
|
|
}
|
|
}
|
|
else {
|
|
int ro = 0;
|
|
for(int z = 0; z < sys.n_cvars; z++) {
|
|
cv = &sys.cvars[z];
|
|
con_fmt_cvar(cv, fmt);
|
|
ro += cv->readonly ? 1 : 0;
|
|
}
|
|
logcu(STR_CMD_CVARLIST, sys.n_cvars, ro);
|
|
}
|
|
}
|
|
|
|
void con_fmt_ccmd(ccmd_t *cmd, char *str) {
|
|
logcu("%s "COL_NEON"%s "COL_DGRAY"["COL_LGRAY"%d .. %d"COL_DGRAY"]", cmd->name, cmd->args, cmd->min, cmd->max);
|
|
}
|
|
|
|
void con_cmd_ccmd(ccmd_t *cmd, const char **argv, int argc) {
|
|
ccmd_t *ccmd;
|
|
char fmt[128];
|
|
if(argc) {
|
|
for(int z = 0; z < argc; z++) {
|
|
ccmd = con_get(argv[z]);
|
|
if(!ccmd) {
|
|
logce(STR_CCMD_UNKNOWN, argv[z]);
|
|
continue;
|
|
}
|
|
con_fmt_ccmd(ccmd, fmt);
|
|
}
|
|
}
|
|
else {
|
|
for(int z = 0; z < sys.n_ccmds; z++) {
|
|
ccmd = &sys.ccmds[z];
|
|
con_fmt_ccmd(ccmd, fmt);
|
|
}
|
|
logcu(STR_CMD_CCMDLIST, sys.n_ccmds);
|
|
}
|
|
}
|
|
|
|
void con_cmd_memdump(ccmd_t *cmd, const char **argv, int argc) {
|
|
logcu("base : %12.3f MB (%5.2f %%), 1 block (%5.2f %%)", ((float)SYS_BASE) / 1024.0f / 1024.0f, ((float)SYS_BASE) / ((float)sys.mem_alloc) * 100.0f, 100.0f / ((float)sys.mem_blocks));
|
|
for(int z = 0; z < MEM_CATS; z++) {
|
|
logcu("%-10s: %12.3f MB (%5.2f %%), %6lld block%c (%5.2f %%)", mem_types[z], ((float)sys.mem_pool_sizes[z]) / 1024.0f / 1024.0f, ((float)sys.mem_pool_sizes[z]) / ((float)sys.mem_alloc) * 100.0f,
|
|
sys.mem_pool_blocks[z], sys.mem_pool_blocks[z] == 1 ? ' ' : 's', ((float)sys.mem_pool_blocks[z]) / ((float)sys.mem_blocks) * 100.0f);
|
|
}
|
|
logcu("total : %12.3f MB (peak: %.3f MB), %lld blocks", ((float)sys.mem_alloc) / 1024.0f / 1024.0f, ((float)sys.mem_peak) / 1024.0f / 1024.0f, sys.mem_blocks);
|
|
}
|
|
|
|
byte plr_queue(const char *dmxname, const char *drumname, const char **files, int count);
|
|
void plr_end();
|
|
|
|
void con_cmd_play(ccmd_t *cmd, const char **argv, int argc) {
|
|
const char *bank = NULL;
|
|
const char *drum = NULL;
|
|
int id = snd.mid_bank;
|
|
if(argc) {
|
|
if(!strcmp(argv[0], "-b")) {
|
|
if(argc < 2) {
|
|
logce(STR_CMD_ARGREQ, "-b");
|
|
for(int z = 0; z < 32; z++) {
|
|
logce("#%02d -- %s", z, z < 31 ? snd_banknames[z] : "[custom]");
|
|
}
|
|
return;
|
|
}
|
|
if(!str_parse_enum(argv[1], snd_banknames, 31, &id)) {
|
|
bank = argv[1];
|
|
}
|
|
argv += 2;
|
|
argc -= 2;
|
|
}
|
|
else if(!strcmp(argv[0], "-B")) {
|
|
if(argc < 3) {
|
|
logce(STR_CMD_ARGREQS, "-B", 2);
|
|
return;
|
|
}
|
|
bank = argv[1];
|
|
drum = argv[2];
|
|
argv += 3;
|
|
argc -= 3;
|
|
}
|
|
if(!argc) {
|
|
logcu(STR_CMD_PLAY_BANKID, bank ? 31 : id);
|
|
return;
|
|
}
|
|
if(plr_queue(bank ? bank : snd_bankfiles[id], drum, argv, argc))
|
|
logcu(STR_CMD_PLAY_QUEUED, argc);
|
|
}
|
|
else {
|
|
if(snd.mid_queued) {
|
|
logcu(STR_CMD_PLAY_PLAYING, snd.mid_queued);
|
|
for(int z = 0; z < snd.mid_queued; z++) {
|
|
if(z != (snd.mid_queued - 1))
|
|
snd.mid_queue[z+1][-1] = 0;
|
|
logcu("%d. -- %s", z + 1, &(snd.mid_queue[z])[6]);
|
|
if(z != (snd.mid_queued - 1))
|
|
snd.mid_queue[z+1][-1] = '\n';
|
|
}
|
|
}
|
|
else {
|
|
logcu(STR_CMD_PLAY_STOPPED, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void con_cmd_stop(ccmd_t *cmd, const char **argv, int argc) {
|
|
if(snd.mid_queued)
|
|
logcu(STR_CMD_PLAY_ENDED, NULL);
|
|
else
|
|
logcu(STR_CMD_PLAY_STOPPED, NULL);
|
|
plr_end();
|
|
}
|
|
|
|
#define theme_add(str) \
|
|
style = (style_t*)tbl_push(&sys.themes);\
|
|
style->name = str;
|
|
|
|
#define theme_window(bdrtop, bdrbtm, top, btm, text) \
|
|
style->wbrdr_top = bdrtop;\
|
|
style->wbrdr_btm = bdrbtm;\
|
|
style->win_top = top;\
|
|
style->win_btm = btm;\
|
|
style->text_win = text;
|
|
|
|
#define theme_border(top, btm, size) \
|
|
style->brdr_top = top;\
|
|
style->brdr_btm = btm;\
|
|
style->border = size;
|
|
|
|
#define theme_background(top, btm) \
|
|
style->bg_top = top;\
|
|
style->bg_btm = btm;
|
|
|
|
#define theme_base(top, btm, text, label) \
|
|
style->fill_top = top;\
|
|
style->fill_btm = btm;\
|
|
style->text_base = text;\
|
|
style->text_label = label;
|
|
|
|
#define theme_field(top, btm, text) \
|
|
style->field_top = top;\
|
|
style->field_btm = btm;\
|
|
style->text_field = text;
|
|
|
|
#define theme_slider(handle) \
|
|
style->slider_width = handle;
|
|
|
|
#define theme_select(presstop, pressbtm, hovertop, hoverbtm, sel, cur) \
|
|
style->press_top = presstop;\
|
|
style->press_btm = pressbtm;\
|
|
style->hover_top = hovertop;\
|
|
style->hover_btm = hoverbtm;\
|
|
style->select = sel;\
|
|
style->cursor = cur;
|
|
|
|
void con_cmd_themedump(ccmd_t *cmd, const char **argv, int argc) {
|
|
logcu("theme_add(STR_THEME_%s);", argc ? argv[0] : "");
|
|
logcu("theme_window(0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x);", sys.style.wbrdr_top & 0xffffff, sys.style.wbrdr_btm & 0xffffff, sys.style.win_top & 0xffffff, sys.style.win_btm & 0xffffff, sys.style.text_win & 0xffffff);
|
|
logcu("theme_border(0x%06x, 0x%06x, %d);", sys.style.brdr_top & 0xffffff, sys.style.brdr_btm & 0xffffff, sys.style.border);
|
|
logcu("theme_background(0x%06x, 0x%06x);", sys.style.bg_top & 0xffffff, sys.style.bg_btm & 0xffffff);
|
|
logcu("theme_base(0x%06x, 0x%06x, 0x%06x, 0x%06x);", sys.style.fill_top & 0xffffff, sys.style.fill_btm & 0xffffff, sys.style.text_base & 0xffffff, sys.style.text_label & 0xffffff);
|
|
logcu("theme_field(0x%06x, 0x%06x, 0x%06x);", sys.style.field_top & 0xffffff, sys.style.field_btm & 0xffffff, sys.style.text_field & 0xffffff);
|
|
logcu("theme_slider(%d);", sys.style.slider_width);
|
|
logcu("theme_select(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x);", sys.style.press_top, sys.style.press_btm, sys.style.hover_top, sys.style.hover_btm, sys.style.select, sys.style.cursor);
|
|
}
|
|
|
|
void con_reg() {
|
|
con_add("cvar", "[cvar ...]", con_cmd_cvar, 0, CCMD_UNLIMITED);
|
|
con_add("ccmd", "[ccmd ...]", con_cmd_ccmd, 0, CCMD_UNLIMITED);
|
|
con_add("memdump", "", con_cmd_memdump, 0, 0);
|
|
con_add("play", "[-b <bank|id> | -B <bank> <drum>] [midi ...]", con_cmd_play, 0, CCMD_UNLIMITED);
|
|
con_add("stop", "", con_cmd_stop, 0, 0);
|
|
con_add("themedump", "[id]", con_cmd_themedump, 0, 1);
|
|
}
|
|
|
|
void con_init() {
|
|
ccmd_t *cmd;
|
|
con_reg();
|
|
smap_init(&sys.ccmd_map, 1, MEM_SYSTEM);
|
|
for(int z = 0; z < sys.n_ccmds; z++) {
|
|
cmd = &sys.ccmds[z];
|
|
smap_put(&sys.ccmd_map, cmd->name, cmd);
|
|
}
|
|
}
|
|
|
|
void con_end() {
|
|
smap_clear(&sys.ccmd_map);
|
|
}
|
|
|
|
void con_resize(int size) {
|
|
for(int z = sys.hud_size; z < size; z++) {
|
|
sys.hud_msgs[z].message = NULL;
|
|
}
|
|
sys.hud_size = size;
|
|
if(sys.hud_pos >= sys.hud_size)
|
|
sys.hud_pos = 0;
|
|
}
|
|
|
|
gui_t *gui_get(window_t *win, int id);
|
|
void gui_update_text(gui_t *elem);
|
|
void gui_text_update_cur(gui_t *elem, int offset, byte shift);
|
|
|
|
void log_sys(const char *msg, int length, int offset) {
|
|
char c;
|
|
if(sys.con_timestamps ^ 1) {
|
|
length -= offset;
|
|
msg += offset;
|
|
offset = 0;
|
|
}
|
|
if((sys.log_len + length + 2) > CON_BUF) {
|
|
offset = (length + 2) > 1024 ? (length + 2) : 1024;
|
|
while(c = sys.con_buf[offset++]) {
|
|
if(c == '\n')
|
|
break;
|
|
}
|
|
offset -= c ? 0 : 1;
|
|
sys.log_len -= offset;
|
|
memmove(sys.con_buf, &sys.con_buf[offset], sys.log_len);
|
|
}
|
|
sys.con_buf[sys.log_len] = '\n';
|
|
sys.log_len += 1;
|
|
memcpy(&sys.con_buf[sys.log_len], msg, length);
|
|
sys.log_len += length;
|
|
sys.con_buf[sys.log_len] = 0;
|
|
if(sys.console && sys.console->open) {
|
|
gui_t *elem = gui_get(sys.console, 5);
|
|
if(sys.con_autoscroll)
|
|
elem->sel_start = elem->sel_end = elem->sel_drag = sys.log_len;
|
|
gui_update_text(elem);
|
|
if(elem->sel_start >= 0)
|
|
gui_text_update_cur(elem, elem->sel_start, 1);
|
|
}
|
|
}
|
|
|
|
void log_hud(window_t *win, const char *fmt, ...) {
|
|
conmsg_t *con;
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
int length = vsnprintf(sys.log_buf, LOG_BUF, fmt, ap);
|
|
if((sys.hud_len + length + 2) > HUD_BUF) {
|
|
char c;
|
|
int offset = (length + 2) > 1024 ? (length + 2) : 1024;
|
|
while(c = sys.hud_buf[offset++]) {
|
|
if(c == '\n')
|
|
break;
|
|
}
|
|
offset -= c ? 0 : 1;
|
|
sys.hud_len -= offset;
|
|
memmove(sys.hud_buf, &sys.hud_buf[offset], sys.hud_len);
|
|
for(int z = 0; z < sys.hud_size; z++) {
|
|
con = &sys.hud_msgs[z];
|
|
if(con->message) {
|
|
if((con->offset -= offset) < 0)
|
|
con->message = NULL;
|
|
else
|
|
con->message -= offset;
|
|
}
|
|
}
|
|
}
|
|
sys.hud_buf[sys.hud_len] = '\n';
|
|
sys.hud_len += 1;
|
|
memcpy(&sys.hud_buf[sys.hud_len], sys.log_buf, length);
|
|
if(sys.hud_size) {
|
|
con = &sys.hud_msgs[sys.hud_pos];
|
|
con->message = &sys.hud_buf[sys.hud_len];
|
|
con->offset = sys.hud_len;
|
|
con->length = length;
|
|
con->time = sys.tmr_current;
|
|
con->window = win;
|
|
if(++(sys.hud_pos) >= sys.hud_size)
|
|
sys.hud_pos = 0;
|
|
}
|
|
sys.hud_len += length;
|
|
sys.hud_buf[sys.hud_len] = 0;
|
|
va_end(ap);
|
|
}
|