#include "charwin.h" static const unsigned mul40[25] = { 0, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 520, 560, 600, 640, 680, 720, 760, 800, 840, 880, 920, 960 }; static __native inline void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n) { for(char i=0; isx = sx; win->sy = sy; win->wx = wx; win->wy = wy; win->cx = 0; win->cy = 0; win->sp = screen + mul40[sy] + sx; win->cp = (char *)0xd800 + mul40[sy] + sx; } void cwin_clear(CharWin * win) { cwin_fill(win, ' ', 1); } void cwin_fill(CharWin * win, char ch, char color) { char *sp = win->sp, * cp = win->cp; for(char y=0; ywy; y++) { fill_fwd(sp, cp, ch, color, win->wx); sp += 40; cp += 40; } } void cwin_cursor_show(CharWin * win, bool show) { char * cp = win->sp + mul40[win->cy] + win->cx; if (show) *cp |= 0x80; else *cp &= 0x7f; } void cwin_cursor_move(CharWin * win, char cx, char cy) { win->cx = cx; win->cy = cy; } bool cwin_cursor_left(CharWin * win) { if (win->cx > 0) { win->cx--; return true; } return false; } bool cwin_cursor_right(CharWin * win) { if (win->cx + 1 < win->wx) { win->cx++; return true; } return false; } bool cwin_cursor_up(CharWin * win) { if (win->cy > 0) { win->cy--; return true; } return false; } bool cwin_cursor_down(CharWin * win) { if (win->cy + 1 < win->wy) { win->cy++; return true; } return false; } bool cwin_cursor_newline(CharWin * win) { win->cx = 0; if (win->cy + 1 < win->wy) { win->cy++; return true; } return false; } bool cwin_cursor_forward(CharWin * win) { if (win->cx + 1 < win->wx) { win->cx++; return true; } else if (win->cy + 1 < win->wy) { win->cx = 0; win->cy++; return true; } return false; } bool cwin_cursor_backward(CharWin * win) { if (win->cx > 0) { win->cx--; return true; } else if (win->cy > 0) { win->cx = win->wx - 1; win->cy--; return true; } return false; } //static char p2smap[] = {0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x40, 0x60}; static char p2smap[] = {0x00, 0x00, 0x40, 0x20, 0x80, 0xc0, 0x80, 0x80}; //static char s2pmap[] = {0x40, 0x20, 0x60, 0xa0, 0x40, 0x20, 0x60, 0xa0}; static char s2pmap[] = {0x40, 0x00, 0x20, 0xc0, 0xc0, 0x80, 0xa0, 0x40}; static inline char p2s(char ch) { return ch ^ p2smap[ch >> 5]; } static inline char s2p(char ch) { return ch ^ s2pmap[ch >> 5]; } void cwin_read_string(CharWin * win, char * buffer) { char * sp = win->sp; char i = 0; for(char y=0; ywy; y++) { for(char x=0; xwx; x++) { buffer[i++] = s2p(sp[x]); } sp += 40; } while (i > 0 && buffer[i - 1] == ' ') i--; buffer[i] = 0; } void cwin_write_string(CharWin * win, const char * buffer) { char * dp = win->sp; for(char y=0; ywy; y++) { for(char x=0; xwx; x++) { char ch = *buffer; if (ch) { dp[x] = p2s(ch); buffer++; } else dp[x] = ' '; } dp += 40; } } void cwin_put_char(CharWin * win, char ch, char color) { cwin_putat_char(win, win->cx, win->cy, ch, color); win->cx++; if (win->cx == win->wx) { win->cx = 0; win->cy++; } } void cwin_put_chars(CharWin * win, const char * chars, char num, char color) { cwin_putat_chars(win, win->cx, win->cy, chars, color); win->cx += num; if (win->cx >= win->wx) { win->cx = 0; win->cy++; } } char cwin_put_string(CharWin * win, const char * str, char color) { char n = cwin_putat_string(win, win->cx, win->cy, str, color); win->cx += n; if (win->cx >= win->wx) { win->cx = 0; win->cy++; } return n; } void cwin_put_char_raw(CharWin * win, char ch, char color) { cwin_putat_char_raw(win, win->cx, win->cy, ch, color); win->cx++; if (win->cx == win->wx) { win->cx = 0; win->cy++; } } void cwin_put_chars_raw(CharWin * win, const char * chars, char num, char color) { cwin_putat_chars_raw(win, win->cx, win->cy, chars, color); win->cx += num; if (win->cx >= win->wx) { win->cx = 0; win->cy++; } } char cwin_put_string_raw(CharWin * win, const char * str, char color) { char n = cwin_putat_string_raw(win, win->cx, win->cy, str, color); win->cx += n; if (win->cx >= win->wx) { win->cx = 0; win->cy++; } return n; } void cwin_putat_char(CharWin * win, char x, char y, char ch, char color) { int offset = mul40[y] + x; win->sp[offset] = p2s(ch); win->cp[offset] = color; } #pragma native(cwin_putat_char) void cwin_putat_chars(CharWin * win, char x, char y, const char * chars, char num, char color) { int offset = mul40[y] + x; char * sp = win->sp + offset; char * cp = win->cp + offset; for(char i=0; isp + offset; char * cp = win->cp + offset; char i = 0; while (char ch = str[i]) { sp[i] = p2s(ch); cp[i] = color; i++; } return i; } #pragma native(cwin_putat_string) void cwin_putat_char_raw(CharWin * win, char x, char y, char ch, char color) { int offset = mul40[y] + x; win->sp[offset] = ch; win->cp[offset] = color; } #pragma native(cwin_putat_char_raw) void cwin_putat_chars_raw(CharWin * win, char x, char y, const char * chars, char num, char color) { int offset = mul40[y] + x; char * sp = win->sp + offset; char * cp = win->cp + offset; for(char i=0; isp + offset; char * cp = win->cp + offset; char i = 0; while (char ch = str[i]) { sp[i] = ch; cp[i] = color; i++; } return i; } #pragma native(cwin_putat_string_raw) char cwin_getat_char(CharWin * win, char x, char y) { char * sp = win->sp + mul40[y] + x; return s2p(*sp); } #pragma native(cwin_getat_char) void cwin_getat_chars(CharWin * win, char x, char y, char * chars, char num) { char * sp = win->sp + mul40[y] + x; for(char i=0; isp + mul40[y] + x; return *sp; } #pragma native(cwin_getat_chars_raw) void cwin_getat_chars_raw(CharWin * win, char x, char y, char * chars, char num) { char * sp = win->sp + mul40[y] + x; for(char i=0; isp + offset; char * cp = win->cp + offset; for(char i=0; isp + offset; char * cp = win->cp + offset; for(char i=0; isp + offset; for(char i=0; isp + offset; for(char i=0; iwy - 1, rx = win->wx - 1; char * sp = win->sp + mul40[y]; char * cp = win->cp + mul40[y]; while (y > win->cy) { copy_bwd(sp + 1, sp, cp + 1, cp, rx); sp -= 40; cp -= 40; sp[40] = sp[rx]; cp[40] = cp[rx]; y--; } sp += win->cx; cp += win->cx; rx -= win->cx; copy_bwd(sp + 1, sp, cp + 1, cp, rx); sp[0] = ' '; } void cwin_delete_char(CharWin * win) { char * sp = win->sp + mul40[win->cy]; char * cp = win->cp + mul40[win->cy]; char x = win->cx, rx = win->wx - 1; copy_fwd(sp + x, sp + x + 1, cp + x, cp + x + 1, rx - x); char y = win->cy + 1; while (y < win->wy) { sp[rx] = sp[40]; cp[rx] = cp[40]; sp += 40; cp += 40; copy_fwd(sp, sp + 1, cp, cp + 1, rx); y++; } sp[rx] = ' '; } int cwin_getch(void) { __asm { L1: jsr 0xffe4 cmp #0 beq L1 sta accu lda #0 sta accu + 1 } } int cwin_checkch(void) { __asm { L1: jsr 0xffe4 sta accu lda #0 sta accu + 1 } } bool cwin_edit_char(CharWin * win, char ch) { switch (ch) { case 13: case 3: return true; case 19: win->cx = 0; win->cy = 0; return false; case 147: cwin_clear(win); win->cx = 0; win->cy = 0; return false; case 17: cwin_cursor_down(win); return false; case 145: // CRSR_UP cwin_cursor_up(win); return false; case 29: cwin_cursor_forward(win); return false; case 157: cwin_cursor_backward(win); return false; case 20: if (cwin_cursor_backward(win)) cwin_delete_char(win); return false; default: if (ch >= 32 && ch < 128 || ch >= 160) { if (win->cy + 1 < win->wy || win->cx + 1 < win->wx) { cwin_insert_char(win); cwin_put_char(win, ch, 1); } } return false; } } char cwin_edit(CharWin * win) { for(;;) { cwin_cursor_show(win, true); char ch = cwin_getch(); cwin_cursor_show(win, false); if (cwin_edit_char(win, ch)) return ch; } } void cwin_scroll_left(CharWin * win, char by) { char * sp = win->sp; char * cp = win->cp; char rx = win->wx - by; for(char y=0; ywy; y++) { copy_fwd(sp, sp + by, cp, cp + by, rx); } } void cwin_scroll_right(CharWin * win, char by) { char * sp = win->sp; char * cp = win->cp; char rx = win->wx - by; for(char y=0; ywy; y++) { copy_bwd(sp + by, sp, cp + by, cp, rx); sp += 40; cp += 40; } } void cwin_scroll_up(CharWin * win, char by) { char * sp = win->sp; char * cp = win->cp; char rx = win->wx; int dst = mul40[by]; for(char y=0; ywy - by; y++) { copy_fwd(sp, sp + dst, cp, cp + dst, rx); sp += 40; cp += 40; } } void cwin_scroll_down(CharWin * win, char by) { char * sp = win->sp + mul40[win->wy]; char * cp = win->cp + mul40[win->wy]; char rx = win->wx; int dst = mul40[by]; for(char y=0; ywy - by; y++) { sp -= 40; cp -= 40; copy_fwd(sp, sp - dst, cp, cp - dst, rx); } } void cwin_fill_rect_raw(CharWin * win, char x, char y, char w, char h, char ch, char color) { if (w > 0) { char * sp = win->sp + mul40[y] + x; char * cp = win->cp + mul40[y] + x; for(char y=0; y