Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 1326 → Rev 1327

/sved/trunk/sved.c
49,8 → 49,18
 
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */
static unsigned char scheme[] = {0x07, 0x70, 0x70, 0x70, 0x70, 0xf0};
 
static unsigned char screenw, screenh;
 
//static union {
static struct {
unsigned char from;
unsigned char to;
// };
// unsigned short fromto;
} uidirty = {0, 0xff}; /* make sure to redraw entire UI at first run */
//} uidirty = {0xff, 0};
 
#define SCROLL_CURSOR 0xB1
 
struct line {
174,7 → 184,7
}
 
 
static void ui_msg(const char *msg, unsigned char *uidirtyfrom, unsigned char *uidirtyto, unsigned char attr) {
static void ui_msg(const char *msg, unsigned char attr) {
unsigned short x, y, msglen, i;
msglen = strlen(msg);
y = (screenh - 4) >> 1;
182,8 → 192,8
for (i = y+2; i >= y; i--) mdr_cout_char_rep(i, x, ' ', attr, msglen + 2);
mdr_cout_str(y+1, x+1, msg, attr, msglen);
 
if (*uidirtyfrom > y) *uidirtyfrom = y;
if (*uidirtyto < y+2) *uidirtyto = y+2;
if (uidirty.from > y) uidirty.from = y;
if (uidirty.to < y+2) uidirty.to = y+2;
}
 
 
211,7 → 221,7
}
 
 
static void ui_refresh(const struct file *db, unsigned char uidirtyfrom, unsigned char uidirtyto) {
static void ui_refresh(const struct file *db) {
unsigned char x;
const struct line far *l;
unsigned char y = db->cursorposy;
223,14 → 233,14
#endif
 
/* rewind cursor line to first line that needs redrawing */
for (l = db->cursor; y > uidirtyfrom; y--) l = l->prev;
for (l = db->cursor; y > uidirty.from; y--) l = l->prev;
 
/* iterate over lines and redraw whatever needs to be redrawn */
for (; l != NULL; l = l->next, y++) {
 
/* skip lines that do not need to be refreshed */
if (y < uidirtyfrom) continue;
if (y > uidirtyto) break;
if (y < uidirty.from) continue;
if (y > uidirty.to) break;
 
x = 0;
if (db->xoffset < l->len) {
255,7 → 265,7
 
/* fill all lines below if empty (and they need to be redrawn) */
if (l == NULL) {
while ((y < screenh - 1) && (y < uidirtyto)) {
while ((y < screenh - 1) && (y < uidirty.to)) {
mdr_cout_char_rep(y++, 0, ' ', scheme[COL_TXT], screenw - 1);
}
}
262,14 → 272,14
}
 
 
static void check_cursor_not_after_eol(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void check_cursor_not_after_eol(struct file *db) {
if (db->xoffset + db->cursorposx <= db->cursor->len) return;
 
if (db->cursor->len < db->xoffset) {
db->cursorposx = 0;
db->xoffset = db->cursor->len;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
} else {
db->cursorposx = db->cursor->len - db->xoffset;
}
276,12 → 286,12
}
 
 
static void cursor_up(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_up(struct file *db) {
if (db->cursor->prev != NULL) {
db->cursor = db->cursor->prev;
if (db->cursorposy == 0) {
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
} else {
db->cursorposy -= 1;
}
289,82 → 299,82
}
 
 
static void cursor_eol(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_eol(struct file *db) {
/* adjust xoffset to make sure eol is visible on screen */
if (db->xoffset > db->cursor->len) {
db->xoffset = db->cursor->len - 1;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
}
 
if (db->xoffset + screenw - 1 <= db->cursor->len) {
db->xoffset = db->cursor->len - screenw + 2;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
}
db->cursorposx = db->cursor->len - db->xoffset;
}
 
 
static void cursor_down(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_down(struct file *db) {
if (db->cursor->next != NULL) {
db->cursor = db->cursor->next;
if (db->cursorposy < screenh - 2) {
db->cursorposy += 1;
} else {
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
}
}
}
 
 
static void cursor_left(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_left(struct file *db) {
if (db->cursorposx > 0) {
db->cursorposx -= 1;
} else if (db->xoffset > 0) {
db->xoffset -= 1;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
} else if (db->cursor->prev != NULL) { /* jump to end of line above */
cursor_up(db, uidirtyfrom, uidirtyto);
cursor_eol(db, uidirtyfrom, uidirtyto);
cursor_up(db);
cursor_eol(db);
}
}
 
 
static void cursor_home(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_home(struct file *db) {
db->cursorposx = 0;
if (db->xoffset != 0) {
db->xoffset = 0;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
}
}
 
 
static void cursor_right(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void cursor_right(struct file *db) {
if (db->cursor->len > db->xoffset + db->cursorposx) {
if (db->cursorposx < screenw - 2) {
db->cursorposx += 1;
} else {
db->xoffset += 1;
*uidirtyfrom = 0;
*uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
}
} else {
cursor_down(db, uidirtyfrom, uidirtyto);
cursor_home(db, uidirtyfrom, uidirtyto);
cursor_down(db);
cursor_home(db);
}
}
 
 
static void del(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void del(struct file *db) {
if (db->cursorposx + db->xoffset < db->cursor->len) {
_fmemmove(db->cursor->payload + db->cursorposx + db->xoffset, db->cursor->payload + db->cursorposx + db->xoffset + 1, db->cursor->len - db->cursorposx - db->xoffset);
db->cursor->len -= 1; /* do this AFTER memmove so the copy includes the nul terminator */
*uidirtyfrom = db->cursorposy;
*uidirtyto = db->cursorposy;
uidirty.from = db->cursorposy;
uidirty.to = db->cursorposy;
} else if (db->cursor->next != NULL) { /* cursor is at end of line: merge current line with next one (if there is a next one) */
struct line far *nextline = db->cursor->next;
if (db->cursor->next->len > 0) {
379,19 → 389,19
db->cursor->next->prev = db->cursor;
if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; /* in case realloc changed my pointer */
_ffree(nextline);
*uidirtyfrom = db->cursorposy;
*uidirtyto = 0xff;
uidirty.from = db->cursorposy;
uidirty.to = 0xff;
}
}
 
 
static void bkspc(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void bkspc(struct file *db) {
 
/* backspace is basically "left + del", not applicable only if cursor is on 1st byte of the file */
if ((db->cursorposx == 0) && (db->xoffset == 0) && (db->cursor->prev == NULL)) return;
 
cursor_left(db, uidirtyfrom, uidirtyto);
del(db, uidirtyfrom, uidirtyto);
cursor_left(db);
del(db);
}
 
 
570,7 → 580,7
}
 
 
static void insert_in_line(struct file *db, const char *databuf, unsigned short len, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
static void insert_in_line(struct file *db, const char *databuf, unsigned short len) {
struct line far *n;
n = _frealloc(db->cursor, sizeof(struct line) + db->cursor->len + len);
if (n != NULL) {
580,12 → 590,12
db->cursor = n;
_fmemmove(db->cursor->payload + off + len, db->cursor->payload + off, db->cursor->len - off + 1);
db->cursor->len += len;
*uidirtyfrom = db->cursorposy;
*uidirtyto = db->cursorposy;
uidirty.from = db->cursorposy;
uidirty.to = db->cursorposy;
while (len--) {
db->cursor->payload[off++] = *databuf;
databuf++;
cursor_right(db, uidirtyfrom, uidirtyto);
cursor_right(db);
}
}
}
594,7 → 604,6
int main(void) {
const char *fname;
struct file *db;
unsigned char uidirtyfrom = 0, uidirtyto = 0xff; /* make sure to redraw entire UI at first run */
 
{
char nlspath[128], lang[8];
618,27 → 627,27
for (;;) {
int k;
 
check_cursor_not_after_eol(db, &uidirtyfrom, &uidirtyto);
check_cursor_not_after_eol(db);
mdr_cout_locate(db->cursorposy, db->cursorposx);
 
if (uidirtyfrom != 0xff) {
ui_refresh(db, uidirtyfrom, uidirtyto);
uidirtyfrom = 0xff;
if (uidirty.from != 0xff) {
ui_refresh(db);
uidirty.from = 0xff;
}
 
k = keyb_getkey();
 
if (k == 0x150) { /* down */
cursor_down(db, &uidirtyfrom, &uidirtyto);
cursor_down(db);
 
} else if (k == 0x148) { /* up */
cursor_up(db, &uidirtyfrom, &uidirtyto);
cursor_up(db);
 
} else if (k == 0x14D) { /* right */
cursor_right(db, &uidirtyfrom, &uidirtyto);
cursor_right(db);
 
} else if (k == 0x14B) { /* left */
cursor_left(db, &uidirtyfrom, &uidirtyto);
cursor_left(db);
 
} else if (k == 0x149) { /* pgup */
// TODO
647,10 → 656,10
// TODO
 
} else if (k == 0x147) { /* home */
cursor_home(db, &uidirtyfrom, &uidirtyto);
cursor_home(db);
 
} else if (k == 0x14F) { /* end */
cursor_eol(db, &uidirtyfrom, &uidirtyto);
cursor_eol(db);
 
} else if (k == 0x1B) { /* ESC */
break;
664,41 → 673,41
/* move cursor to the (new) line below */
db->cursorposx = 0;
if (db->cursorposy < screenh - 2) {
uidirtyfrom = db->cursorposy;
uidirty.from = db->cursorposy;
db->cursorposy++;
} else {
uidirtyfrom = 0;
uidirty.from = 0;
}
uidirtyto = 0xff;
uidirty.to = 0xff;
} else {
/* ERROR: OUT OF MEMORY */
}
 
} else if (k == 0x153) { /* DEL */
del(db, &uidirtyfrom, &uidirtyto);
del(db);
 
} else if (k == 0x008) { /* BKSPC */
bkspc(db, &uidirtyfrom, &uidirtyto);
bkspc(db);
 
} else if ((k >= 0x20) && (k <= 0xff)) { /* "normal" character */
char c = k;
insert_in_line(db, &c, 1, &uidirtyfrom, &uidirtyto);
insert_in_line(db, &c, 1);
 
} else if (k == 0x009) { /* TAB */
const char *tab = " ";
insert_in_line(db, tab, 8, &uidirtyfrom, &uidirtyto);
insert_in_line(db, tab, 8);
 
} else if (k == 0x13b) { /* F1 */
ui_help();
uidirtyfrom = 0;
uidirtyto = 0xff;
uidirty.from = 0;
uidirty.to = 0xff;
 
} else if (k == 0x13f) { /* F5 */
if (savefile(db) == 0) {
ui_msg(svarlang_str(0, 2), &uidirtyfrom, &uidirtyto, scheme[COL_MSG]);
ui_msg(svarlang_str(0, 2), scheme[COL_MSG]);
mdr_bios_tickswait(11); /* 11 ticks is about 600 ms */
} else {
ui_msg(svarlang_str(0, 3), &uidirtyfrom, &uidirtyto, scheme[COL_ERR]);
ui_msg(svarlang_str(0, 3), scheme[COL_ERR]);
mdr_bios_tickswait(36); /* 2s */
}
 
711,28 → 720,28
for (;;) {
if (db->xoffset + db->cursorposx == db->cursor->len) break;
if (db->cursor->payload[db->xoffset + db->cursorposx] == ' ') break;
cursor_right(db, &uidirtyfrom, &uidirtyto);
cursor_right(db);
}
/* now skip to next non-space or end of file */
for (;;) {
cursor_right(db, &uidirtyfrom, &uidirtyto);
cursor_right(db);
if (db->cursor->payload[db->xoffset + db->cursorposx] != ' ') break;
if ((db->cursor->next == NULL) && (db->cursorposx + db->xoffset == db->cursor->len)) break;
}
 
} else if (k == 0x173) { /* CTRL+ArrLeft - jump to prev word */
cursor_left(db, &uidirtyfrom, &uidirtyto);
cursor_left(db);
/* if currently cursor is on a space, then fast-forward to nearest non-space or start of line */
for (;;) {
if ((db->xoffset == 0) && (db->cursorposx == 0)) break;
if (db->cursor->payload[db->xoffset + db->cursorposx] != ' ') break;
cursor_left(db, &uidirtyfrom, &uidirtyto);
cursor_left(db);
}
/* now skip to next space or start of file */
for (;;) {
cursor_left(db, &uidirtyfrom, &uidirtyto);
cursor_left(db);
if (db->cursor->payload[db->xoffset + db->cursorposx] == ' ') {
cursor_right(db, &uidirtyfrom, &uidirtyto);
cursor_right(db);
break;
}
if ((db->cursorposx == 0) && (db->xoffset == 0)) break;