Subversion Repositories SvarDOS

Rev

Rev 1315 | Rev 1317 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1315 Rev 1316
Line 54... Line 54...
54
};
54
};
55
 
55
 
56
struct file {
56
struct file {
57
  struct line far *cursor;
57
  struct line far *cursor;
58
  unsigned short xoffset;
58
  unsigned short xoffset;
-
 
59
  unsigned char cursorposx;
-
 
60
  unsigned char cursorposy;
59
  char lfonly; /* set if line endings are LF (CR/LF otherwise) */
61
  char lfonly; /* set if line endings are LF (CR/LF otherwise) */
60
};
62
};
61
 
63
 
62
 
64
 
63
/* returns non-zero on error */
65
/* returns non-zero on error */
Line 167... Line 169...
167
  mdr_cout_cursor_show();
169
  mdr_cout_cursor_show();
168
#undef MAXLINLEN
170
#undef MAXLINLEN
169
}
171
}
170
 
172
 
171
 
173
 
172
static void ui_refresh(const struct file *db, unsigned char screenw, unsigned char screenh, unsigned char uidirtyfrom, unsigned char uidirtyto, unsigned char y) {
174
static void ui_refresh(const struct file *db, unsigned char screenw, unsigned char screenh, unsigned char uidirtyfrom, unsigned char uidirtyto) {
173
  unsigned char len;
175
  unsigned char len;
174
  const struct line far *l;
176
  const struct line far *l;
-
 
177
  unsigned char y = db->cursorposy;
175
 
178
 
176
#ifdef DBG_REFRESH
179
#ifdef DBG_REFRESH
177
  static char m = 'a';
180
  static char m = 'a';
178
  m++;
181
  m++;
179
  if (m > 'z') m = 'a';
182
  if (m > 'z') m = 'a';
Line 204... Line 207...
204
  }
207
  }
205
 
208
 
206
}
209
}
207
 
210
 
208
 
211
 
209
static void check_cursor_not_after_eol(struct file *db, unsigned char *cursorpos, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
212
static void check_cursor_not_after_eol(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
210
  if (db->xoffset + *cursorpos <= db->cursor->len) return;
213
  if (db->xoffset + db->cursorposx <= db->cursor->len) return;
211
 
214
 
212
  if (db->cursor->len < db->xoffset) {
215
  if (db->cursor->len < db->xoffset) {
213
    *cursorpos = 0;
216
    db->cursorposx = 0;
214
    db->xoffset = db->cursor->len;
217
    db->xoffset = db->cursor->len;
215
    *uidirtyfrom = 0;
218
    *uidirtyfrom = 0;
216
    *uidirtyto = 0xff;
219
    *uidirtyto = 0xff;
217
  } else {
220
  } else {
218
    *cursorpos = db->cursor->len - db->xoffset;
221
    db->cursorposx = db->cursor->len - db->xoffset;
219
  }
222
  }
220
}
223
}
221
 
224
 
222
 
225
 
223
static void cursor_up(struct file *db, unsigned char *cursorposy, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
226
static void cursor_up(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
224
  if (db->cursor->prev != NULL) {
227
  if (db->cursor->prev != NULL) {
225
    db->cursor = db->cursor->prev;
228
    db->cursor = db->cursor->prev;
226
    if (*cursorposy == 0) {
229
    if (db->cursorposy == 0) {
227
      *uidirtyfrom = 0;
230
      *uidirtyfrom = 0;
228
      *uidirtyto = 0xff;
231
      *uidirtyto = 0xff;
229
    } else {
232
    } else {
230
      *cursorposy -= 1;
233
      db->cursorposy -= 1;
231
    }
234
    }
232
  }
235
  }
233
}
236
}
234
 
237
 
235
 
238
 
236
static void cursor_eol(struct file *db, unsigned char *cursorposx, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
239
static void cursor_eol(struct file *db, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
237
  /* adjust xoffset to make sure eol is visible on screen */
240
  /* adjust xoffset to make sure eol is visible on screen */
238
  if (db->xoffset > db->cursor->len) {
241
  if (db->xoffset > db->cursor->len) {
239
    db->xoffset = db->cursor->len - 1;
242
    db->xoffset = db->cursor->len - 1;
240
    *uidirtyfrom = 0;
243
    *uidirtyfrom = 0;
241
    *uidirtyto = 0xff;
244
    *uidirtyto = 0xff;
Line 244... Line 247...
244
  if (db->xoffset + screenw - 1 <= db->cursor->len) {
247
  if (db->xoffset + screenw - 1 <= db->cursor->len) {
245
    db->xoffset = db->cursor->len - screenw + 2;
248
    db->xoffset = db->cursor->len - screenw + 2;
246
    *uidirtyfrom = 0;
249
    *uidirtyfrom = 0;
247
    *uidirtyto = 0xff;
250
    *uidirtyto = 0xff;
248
  }
251
  }
249
  *cursorposx = db->cursor->len - db->xoffset;
252
  db->cursorposx = db->cursor->len - db->xoffset;
250
}
253
}
251
 
254
 
252
 
255
 
253
static void cursor_down(struct file *db, unsigned char *cursorposy, unsigned char screenh, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
256
static void cursor_down(struct file *db, unsigned char screenh, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
254
  if (db->cursor->next != NULL) {
257
  if (db->cursor->next != NULL) {
255
    db->cursor = db->cursor->next;
258
    db->cursor = db->cursor->next;
256
    if (*cursorposy < screenh - 2) {
259
    if (db->cursorposy < screenh - 2) {
257
      *cursorposy += 1;
260
      db->cursorposy += 1;
258
    } else {
261
    } else {
259
      *uidirtyfrom = 0;
262
      *uidirtyfrom = 0;
260
      *uidirtyto = 0xff;
263
      *uidirtyto = 0xff;
261
    }
264
    }
262
  }
265
  }
263
}
266
}
264
 
267
 
265
 
268
 
266
static void cursor_left(struct file *db, unsigned char *cursorposx, unsigned char *cursorposy, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
269
static void cursor_left(struct file *db, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
267
  if (*cursorposx > 0) {
270
  if (db->cursorposx > 0) {
268
    *cursorposx -= 1;
271
    db->cursorposx -= 1;
269
  } else if (db->xoffset > 0) {
272
  } else if (db->xoffset > 0) {
270
    db->xoffset -= 1;
273
    db->xoffset -= 1;
271
    *uidirtyfrom = 0;
274
    *uidirtyfrom = 0;
272
    *uidirtyto = 0xff;
275
    *uidirtyto = 0xff;
273
  } else if (db->cursor->prev != NULL) { /* jump to end of line above */
276
  } else if (db->cursor->prev != NULL) { /* jump to end of line above */
274
    cursor_up(db, cursorposy, uidirtyfrom, uidirtyto);
277
    cursor_up(db, uidirtyfrom, uidirtyto);
275
    cursor_eol(db, cursorposx, screenw, uidirtyfrom, uidirtyto);
278
    cursor_eol(db, screenw, uidirtyfrom, uidirtyto);
276
  }
279
  }
277
}
280
}
278
 
281
 
279
 
282
 
280
static void cursor_home(struct file *db, unsigned char *cursorposx, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
283
static void cursor_home(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
281
  *cursorposx = 0;
284
  db->cursorposx = 0;
282
  if (db->xoffset != 0) {
285
  if (db->xoffset != 0) {
283
    db->xoffset = 0;
286
    db->xoffset = 0;
284
    *uidirtyfrom = 0;
287
    *uidirtyfrom = 0;
285
    *uidirtyto = 0xff;
288
    *uidirtyto = 0xff;
286
  }
289
  }
287
}
290
}
288
 
291
 
289
 
292
 
290
static void cursor_right(struct file *db, unsigned char *cursorposx, unsigned char *cursorposy, unsigned char screenw, unsigned char screenh, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
293
static void cursor_right(struct file *db, unsigned char screenw, unsigned char screenh, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
291
  if (db->cursor->len > db->xoffset + *cursorposx) {
294
  if (db->cursor->len > db->xoffset + db->cursorposx) {
292
    if (*cursorposx < screenw - 2) {
295
    if (db->cursorposx < screenw - 2) {
293
      *cursorposx += 1;
296
      db->cursorposx += 1;
294
    } else {
297
    } else {
295
      db->xoffset += 1;
298
      db->xoffset += 1;
296
      *uidirtyfrom = 0;
299
      *uidirtyfrom = 0;
297
      *uidirtyto = 0xff;
300
      *uidirtyto = 0xff;
298
    }
301
    }
299
  } else {
302
  } else {
300
    cursor_down(db, cursorposy, screenh, uidirtyfrom, uidirtyto);
303
    cursor_down(db, screenh, uidirtyfrom, uidirtyto);
301
    cursor_home(db, cursorposx, uidirtyfrom, uidirtyto);
304
    cursor_home(db, uidirtyfrom, uidirtyto);
302
  }
305
  }
303
}
306
}
304
 
307
 
305
 
308
 
306
static void del(struct file *db, unsigned char cursorposx, unsigned char cursorposy, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
309
static void del(struct file *db, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
307
  if (cursorposx + db->xoffset < db->cursor->len) {
310
  if (db->cursorposx + db->xoffset < db->cursor->len) {
308
    _fmemmove(db->cursor->payload + cursorposx + db->xoffset, db->cursor->payload + cursorposx + db->xoffset + 1, db->cursor->len - cursorposx - db->xoffset);
311
    _fmemmove(db->cursor->payload + db->cursorposx + db->xoffset, db->cursor->payload + db->cursorposx + db->xoffset + 1, db->cursor->len - db->cursorposx - db->xoffset);
309
    db->cursor->len -= 1; /* do this AFTER memmove so the copy includes the nul terminator */
312
    db->cursor->len -= 1; /* do this AFTER memmove so the copy includes the nul terminator */
310
    *uidirtyfrom = cursorposy;
313
    *uidirtyfrom = db->cursorposy;
311
    *uidirtyto = cursorposy;
314
    *uidirtyto = db->cursorposy;
312
  } else if (db->cursor->next != NULL) { /* cursor is at end of line: merge current line with next one (if there is a next one) */
315
  } else if (db->cursor->next != NULL) { /* cursor is at end of line: merge current line with next one (if there is a next one) */
313
    struct line far *nextline = db->cursor->next;
316
    struct line far *nextline = db->cursor->next;
314
    if (db->cursor->next->len > 0) {
317
    if (db->cursor->next->len > 0) {
315
      void far *newptr = _frealloc(db->cursor, sizeof(struct line) + db->cursor->len + db->cursor->next->len + 1);
318
      void far *newptr = _frealloc(db->cursor, sizeof(struct line) + db->cursor->len + db->cursor->next->len + 1);
316
      if (newptr != NULL) {
319
      if (newptr != NULL) {
Line 321... Line 324...
321
    }
324
    }
322
    db->cursor->next = db->cursor->next->next;
325
    db->cursor->next = db->cursor->next->next;
323
    db->cursor->next->prev = db->cursor;
326
    db->cursor->next->prev = db->cursor;
324
    if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; /* in case realloc changed my pointer */
327
    if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; /* in case realloc changed my pointer */
325
    _ffree(nextline);
328
    _ffree(nextline);
326
    *uidirtyfrom = cursorposy;
329
    *uidirtyfrom = db->cursorposy;
327
    *uidirtyto = 0xff;
330
    *uidirtyto = 0xff;
328
  }
331
  }
329
}
332
}
330
 
333
 
331
 
334
 
332
static void bkspc(struct file *db, unsigned char *cursorposx, unsigned char *cursorposy, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
335
static void bkspc(struct file *db, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
333
 
336
 
334
  /* backspace is basically "left + del", not applicable only if cursor is on 1st byte of the file */
337
  /* backspace is basically "left + del", not applicable only if cursor is on 1st byte of the file */
335
  if ((*cursorposx == 0) && (db->xoffset == 0) && (db->cursor->prev == NULL)) return;
338
  if ((db->cursorposx == 0) && (db->xoffset == 0) && (db->cursor->prev == NULL)) return;
336
 
339
 
337
  cursor_left(db, cursorposx, cursorposy, screenw, uidirtyfrom, uidirtyto);
340
  cursor_left(db, screenw, uidirtyfrom, uidirtyto);
338
  del(db, *cursorposx, *cursorposy, uidirtyfrom, uidirtyto);
341
  del(db, uidirtyfrom, uidirtyto);
339
}
342
}
340
 
343
 
341
 
344
 
342
/* a custom argv-parsing routine that looks directly inside the PSP, avoids the need
345
/* a custom argv-parsing routine that looks directly inside the PSP, avoids the need
343
 * of argc and argv, saves some 330 bytes of binary size */
346
 * of argc and argv, saves some 330 bytes of binary size */
Line 455... Line 458...
455
 
458
 
456
int main(void) {
459
int main(void) {
457
  const char *fname;
460
  const char *fname;
458
  struct file db;
461
  struct file db;
459
  unsigned char screenw = 0, screenh = 0;
462
  unsigned char screenw = 0, screenh = 0;
460
  unsigned char cursorposx = 0, cursorposy = 0;
-
 
461
  unsigned char uidirtyfrom = 0, uidirtyto = 0xff; /* make sure to redraw entire UI at first run */
463
  unsigned char uidirtyfrom = 0, uidirtyto = 0xff; /* make sure to redraw entire UI at first run */
462
 
464
 
463
  bzero(&db, sizeof(db));
465
  bzero(&db, sizeof(db));
464
 
466
 
465
  {
467
  {
Line 486... Line 488...
486
  db_rewind(&db);
488
  db_rewind(&db);
487
 
489
 
488
  for (;;) {
490
  for (;;) {
489
    int k;
491
    int k;
490
 
492
 
491
    check_cursor_not_after_eol(&db, &cursorposx, &uidirtyfrom, &uidirtyto);
493
    check_cursor_not_after_eol(&db, &uidirtyfrom, &uidirtyto);
492
    mdr_cout_locate(cursorposy, cursorposx);
494
    mdr_cout_locate(db.cursorposy, db.cursorposx);
493
 
495
 
494
    if (uidirtyfrom != 0xff) {
496
    if (uidirtyfrom != 0xff) {
495
      ui_refresh(&db, screenw, screenh, uidirtyfrom, uidirtyto, cursorposy);
497
      ui_refresh(&db, screenw, screenh, uidirtyfrom, uidirtyto);
496
      uidirtyfrom = 0xff;
498
      uidirtyfrom = 0xff;
497
    }
499
    }
498
 
500
 
499
    k = keyb_getkey();
501
    k = keyb_getkey();
500
 
502
 
501
    if (k == 0x150) { /* down */
503
    if (k == 0x150) { /* down */
502
      cursor_down(&db, &cursorposy, screenh, &uidirtyfrom, &uidirtyto);
504
      cursor_down(&db, screenh, &uidirtyfrom, &uidirtyto);
503
 
505
 
504
    } else if (k == 0x148) { /* up */
506
    } else if (k == 0x148) { /* up */
505
      cursor_up(&db, &cursorposy, &uidirtyfrom, &uidirtyto);
507
      cursor_up(&db, &uidirtyfrom, &uidirtyto);
506
 
508
 
507
    } else if (k == 0x14D) { /* right */
509
    } else if (k == 0x14D) { /* right */
508
      cursor_right(&db, &cursorposx, &cursorposy, screenw, screenh, &uidirtyfrom, &uidirtyto);
510
      cursor_right(&db, screenw, screenh, &uidirtyfrom, &uidirtyto);
509
 
511
 
510
    } else if (k == 0x14B) { /* left */
512
    } else if (k == 0x14B) { /* left */
511
      cursor_left(&db, &cursorposx, &cursorposy, screenw, &uidirtyfrom, &uidirtyto);
513
      cursor_left(&db, screenw, &uidirtyfrom, &uidirtyto);
512
 
514
 
513
    } else if (k == 0x149) { /* pgup */
515
    } else if (k == 0x149) { /* pgup */
514
      // TODO
516
      // TODO
515
 
517
 
516
    } else if (k == 0x151) { /* pgdown */
518
    } else if (k == 0x151) { /* pgdown */
517
      // TODO
519
      // TODO
518
 
520
 
519
    } else if (k == 0x147) { /* home */
521
    } else if (k == 0x147) { /* home */
520
       cursor_home(&db, &cursorposx, &uidirtyfrom, &uidirtyto);
522
       cursor_home(&db, &uidirtyfrom, &uidirtyto);
521
 
523
 
522
    } else if (k == 0x14F) { /* end */
524
    } else if (k == 0x14F) { /* end */
523
       cursor_eol(&db, &cursorposx, screenw, &uidirtyfrom, &uidirtyto);
525
       cursor_eol(&db, screenw, &uidirtyfrom, &uidirtyto);
524
 
526
 
525
    } else if (k == 0x1B) { /* ESC */
527
    } else if (k == 0x1B) { /* ESC */
526
      break;
528
      break;
527
 
529
 
528
    } else if (k == 0x0D) { /* ENTER */
530
    } else if (k == 0x0D) { /* ENTER */
529
      /* add a new line */
531
      /* add a new line */
530
      if (line_add(&db, db.cursor->payload + db.xoffset + cursorposx) == 0) {
532
      if (line_add(&db, db.cursor->payload + db.xoffset + db.cursorposx) == 0) {
531
        /* trim the line above */
533
        /* trim the line above */
532
        db.cursor->prev->len = db.xoffset + cursorposx;
534
        db.cursor->prev->len = db.xoffset + db.cursorposx;
533
        db.cursor->prev->payload[db.cursor->prev->len] = 0;
535
        db.cursor->prev->payload[db.cursor->prev->len] = 0;
534
        /* move cursor to the (new) line below */
536
        /* move cursor to the (new) line below */
535
        cursorposx = 0;
537
        db.cursorposx = 0;
536
        if (cursorposy < screenh - 2) {
538
        if (db.cursorposy < screenh - 2) {
537
          uidirtyfrom = cursorposy;
539
          uidirtyfrom = db.cursorposy;
538
          cursorposy++;
540
          db.cursorposy++;
539
        } else {
541
        } else {
540
          uidirtyfrom = 0;
542
          uidirtyfrom = 0;
541
        }
543
        }
542
        uidirtyto = 0xff;
544
        uidirtyto = 0xff;
543
      } else {
545
      } else {
544
        /* ERROR: OUT OF MEMORY */
546
        /* ERROR: OUT OF MEMORY */
545
      }
547
      }
546
 
548
 
547
    } else if (k == 0x153) {  /* DEL */
549
    } else if (k == 0x153) {  /* DEL */
548
      del(&db, cursorposx, cursorposy, &uidirtyfrom, &uidirtyto);
550
      del(&db, &uidirtyfrom, &uidirtyto);
549
 
551
 
550
    } else if (k == 0x008) { /* BKSPC */
552
    } else if (k == 0x008) { /* BKSPC */
551
      bkspc(&db, &cursorposx, &cursorposy, screenw, &uidirtyfrom, &uidirtyto);
553
      bkspc(&db, screenw, &uidirtyfrom, &uidirtyto);
552
 
554
 
553
    } else if ((k >= 0x20) && (k <= 0xff)) { /* "normal" character */
555
    } else if ((k >= 0x20) && (k <= 0xff)) { /* "normal" character */
554
      struct line far *n;
556
      struct line far *n;
555
      n = _frealloc(db.cursor, sizeof(struct line) + db.cursor->len);
557
      n = _frealloc(db.cursor, sizeof(struct line) + db.cursor->len);
556
      if (n != NULL) {
558
      if (n != NULL) {
557
        unsigned short off = db.xoffset + cursorposx;
559
        unsigned short off = db.xoffset + db.cursorposx;
558
        if (n->prev) n->prev->next = n;
560
        if (n->prev) n->prev->next = n;
559
        if (n->next) n->next->prev = n;
561
        if (n->next) n->next->prev = n;
560
        db.cursor = n;
562
        db.cursor = n;
561
        _fmemmove(db.cursor->payload + off + 1, db.cursor->payload + off, db.cursor->len - off + 1);
563
        _fmemmove(db.cursor->payload + off + 1, db.cursor->payload + off, db.cursor->len - off + 1);
562
        db.cursor->len += 1;
564
        db.cursor->len += 1;
563
        uidirtyfrom = cursorposy;
565
        uidirtyfrom = db.cursorposy;
564
        uidirtyto = cursorposy;
566
        uidirtyto = db.cursorposy;
565
        db.cursor->payload[off] = k;
567
        db.cursor->payload[off] = k;
566
        cursor_right(&db, &cursorposx, &cursorposy, screenw, screenh, &uidirtyfrom, &uidirtyto);
568
        cursor_right(&db, screenw, screenh, &uidirtyfrom, &uidirtyto);
567
      }
569
      }
568
 
570
 
569
    } else if (k == 0x13b) { /* F1 */
571
    } else if (k == 0x13b) { /* F1 */
570
      ui_help(screenw);
572
      ui_help(screenw);
571
      uidirtyfrom = 0;
573
      uidirtyfrom = 0;