#include "sux.h"
uint8_t key_idx = 0;
uint8_t iscol;
uint8_t idx = 3;
uint8_t bcd[4];
int get_keycode(char *str) {
size_t size = strlen(str);
int keycode = 0;
if (size == 1) {
keycode = str[0];
} else if (size > 1) {
int isesc = 0;
for (int i = 0; str[i] != '\0'; i++) {
switch (str[i]) {
case '\x1B': isesc = 1; break;
case '[':
if (isesc) {
i++;
char tmp[3];
switch (str[i]) {
case 'A': keycode = KEY_UP ; break;
case 'B': keycode = KEY_DOWN ; break;
case 'C': keycode = KEY_LEFT ; break;
case 'D': keycode = KEY_RIGHT; break;
default :
if (isdigit(str[i])) {
memcpy(tmp, str+i, 2);
i += 2;
tmp[2] = '\0';
int num = strtol(tmp, NULL, 10);
if (str[i] == '~') {
switch (num) {
case 15: keycode = KEY_F( 5); break;
case 17: keycode = KEY_F( 6); break;
case 18: keycode = KEY_F( 7); break;
case 19: keycode = KEY_F( 8); break;
case 20: keycode = KEY_F( 9); break;
case 21: keycode = KEY_F(10); break;
case 23: keycode = KEY_F(11); break;
case 24: keycode = KEY_F(12); break;
}
}
}
}
} else {
keycode = '[';
}
break;
case 'O':
if (isesc) {
i++;
switch (str[i]) {
case 'P': keycode = KEY_F(1); break;
case 'Q': keycode = KEY_F(2); break;
case 'R': keycode = KEY_F(3); break;
case 'S': keycode = KEY_F(4); break;
}
} else {
keycode = 'O';
}
break;
}
}
}
return keycode;
}
int get_key(WINDOW *scr) {
int c = 0;
uint8_t i = 0;
uint8_t isesc = 0;
size_t size = strlen(key);
if (key[key_idx] == '\0' && size) {
memset(key, 0, size+1);
key_idx = 0;
}
if (!size || !key_idx) {
for (;;) {
c = wgetch(scr);
if (c != ERR) {
key[i++] = c;
isesc = (c == '\x1B');
} else if (i && !isesc) {
key[i] = 0;
key_idx = 0;
size = strlen(key);
break;
}
}
}
if (key[key_idx] != '\0') {
return key[key_idx++];
}
}
void io(uint64_t address, uint8_t rw) {
int x, y;
uint16_t scr_col = 0;
switch (address) {
case STEP_ADDR: step = (!rw) ? addr[STEP_ADDR] : step; break;
case CTRL_ADDR:
if (!rw) {
break;
}
kbd_rdy = 1;
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
#endif
kbd_rdy = 0;
break;
case TX_ADDR:
if (rw) {
break;
}
getyx(scr, y, x);
#if debug
if (!subdbg) {
scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0;
wmove(scr, 28, scr_col);
}
#endif
if (esc) {
#if debug
if (!subdbg && addr[RX_ADDR] == '\n') {
wclrtoeol(scr);
}
#endif
switch (addr[TX_ADDR]) {
case 'A':
if (y > 0)
y--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'B':
if (y < getmaxy(scr))
y++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'C':
if (x < getmaxx(scr))
x++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'D':
if (x > 0)
x--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'H':
if (!bcd[2] && !bcd[3]) {
y = 0;
} else {
y = ((bcd[3]*10) + bcd[2]);
}
if (!bcd[0] && !bcd[1]) {
x = 0;
} else {
x = ((bcd[1]*10) + bcd[0]);
}
#if !debug
wmove(scr, y, x);
#else
mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);
#endif
idx = 3;
bcd[0] = 0;
bcd[1] = 0;
bcd[2] = 0;
bcd[3] = 0;
esc = 0;
break;
case 'S':
#if !debug
wscrl(scr, -1);
#else
#endif
esc = 0;
break;
case 'T':
#if !debug
wscrl(scr, 1);
#else
#endif
esc = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
bcd[idx--] = (addr[address] - '0');
break;
default:
iscol = (addr[address] == ';');
break;
}
} else {
switch (addr[TX_ADDR]) {
case 0xC:
x=0,y=0;
#if !debug
wclear(scr);
wmove(scr, y, x);
#endif
break;
case CURSES_BACKSPACE:
case '\b':
if (x > 0) {
x--;
#if !debug
wmove(scr, y, x);
#endif
}
#if !debug
wdelch(scr);
#else
if (!subdbg) {
scr_col++;
wmove(scr, 28, scr_col--);
wdelch(scr);
wmove(scr, 28, scr_col);
wdelch(scr);
}
#endif
break;
case '\033': esc = 1; break;
case '\n':
x = 0;
y+=1;
#if !debug
wmove(scr, y, x);
#endif
break;
default:
#if !debug
waddch(scr, addr[address]);
#else
if (!subdbg && scr_col < 160) {
if (addr[address] != ' ') {
wprintw(scr, "%02X", addr[address]);
} else {
wprintw(scr, " ");
}
}
#endif
x+=1;
break;
}
}
break;
}
}