Subversion Repositories SvarDOS

Rev

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

Rev 1276 Rev 1282
Line 1... Line 1...
1
/* */
1
/* */
2
 
2
 
3
#include <stdio.h>
3
#include <dos.h>
-
 
4
#include <fcntl.h>
4
#include <stdlib.h>
5
#include <stdlib.h>
5
#include <string.h>
6
#include <string.h>
6
 
7
 
7
#include "mdr\cout.h"
8
#include "mdr\cout.h"
8
#include "mdr\keyb.h"
9
#include "mdr\keyb.h"
9
 
10
 
-
 
11
#include "svarlang\svarlang.h"
-
 
12
 
10
#define COL_TXT        0
13
#define COL_TXT        0
11
#define COL_STATUSBAR1 1
14
#define COL_STATUSBAR1 1
12
#define COL_STATUSBAR2 2
15
#define COL_STATUSBAR2 2
13
#define COL_SCROLLBAR  3
16
#define COL_SCROLLBAR  3
14
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */
17
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */
Line 68... Line 71...
68
  scheme[COL_STATUSBAR2] = 0x78;
71
  scheme[COL_STATUSBAR2] = 0x78;
69
  scheme[COL_SCROLLBAR] = 0x70;
72
  scheme[COL_SCROLLBAR] = 0x70;
70
}
73
}
71
 
74
 
72
 
75
 
73
void ui_basic(unsigned char screenw, unsigned char screenh, const char *fname) {
76
static void ui_basic(unsigned char screenw, unsigned char screenh, const char *fname) {
74
  unsigned char i;
77
  unsigned char i;
75
  const char *s = "HELP";
78
  const char *s = "HELP";
76
  unsigned char helpcol = screenw - (strlen(s) + 4);
79
  unsigned char helpcol = screenw - (strlen(s) + 4);
77
 
80
 
78
  /* clear screen */
81
  /* clear screen */
Line 91... Line 94...
91
    mdr_cout_char(i, screenw - 1, SCROLL_CURSOR, scheme[COL_SCROLLBAR]);
94
    mdr_cout_char(i, screenw - 1, SCROLL_CURSOR, scheme[COL_SCROLLBAR]);
92
  }
95
  }
93
}
96
}
94
 
97
 
95
 
98
 
96
void ui_refresh(const struct linedb *db, unsigned char screenw, unsigned char screenh) {
99
static void ui_refresh(const struct linedb *db, unsigned char screenw, unsigned char screenh, unsigned char uidirtyfrom, unsigned char uidirtyto) {
97
  unsigned char y = 0;
100
  unsigned char y = 0;
98
  unsigned char len;
101
  unsigned char len;
99
  struct line *l;
102
  struct line *l;
100
 
103
 
-
 
104
  /* DEBUG TODO FIXME */
-
 
105
  static char m = 'a';
-
 
106
  m++;
-
 
107
  if (m > 'z') m = 'a';
-
 
108
 
101
  for (l = db->topscreen; l != NULL; l = l->next) {
109
  for (l = db->topscreen; l != NULL; l = l->next) {
-
 
110
 
-
 
111
    /* skip lines that do not to be refreshed */
-
 
112
    if ((y < uidirtyfrom) || (y > uidirtyto)) continue;
-
 
113
 
102
    if (db->xoffset < l->len) {
114
    if (db->xoffset < l->len) {
103
      len = mdr_cout_str(y, 0, l->payload + db->xoffset, scheme[COL_TXT], screenw - 1);
115
      len = mdr_cout_str(y, 0, l->payload + db->xoffset, scheme[COL_TXT], screenw - 1);
104
    } else {
116
    } else {
105
      len = 0;
117
      len = 0;
106
    }
118
    }
107
    while (len < screenw - 1) mdr_cout_char(y, len++, ' ', scheme[COL_TXT]);
119
    while (len < screenw - 1) mdr_cout_char(y, len++, ' ', scheme[COL_TXT]);
-
 
120
 
-
 
121
    /* FIXME DEBUG */
-
 
122
    mdr_cout_char(y, 0, m, scheme[COL_STATUSBAR1]);
-
 
123
 
108
    if (y == screenh - 2) break;
124
    if (y == screenh - 2) break;
109
    y++;
125
    y++;
110
  }
126
  }
111
}
127
}
112
 
128
 
113
 
129
 
114
static void check_cursor_not_after_eol(struct linedb *db, unsigned char *cursorpos) {
130
static void check_cursor_not_after_eol(struct linedb *db, unsigned char *cursorpos, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
115
  if (db->xoffset + *cursorpos <= db->cursor->len) return;
131
  if (db->xoffset + *cursorpos <= db->cursor->len) return;
116
 
132
 
117
  if (db->cursor->len < db->xoffset) {
133
  if (db->cursor->len < db->xoffset) {
118
    *cursorpos = 0;
134
    *cursorpos = 0;
119
    db->xoffset = db->cursor->len;
135
    db->xoffset = db->cursor->len;
-
 
136
    *uidirtyfrom = 0;
-
 
137
    *uidirtyto = 0xff;
120
  } else {
138
  } else {
121
    *cursorpos = db->cursor->len - db->xoffset;
139
    *cursorpos = db->cursor->len - db->xoffset;
122
  }
140
  }
123
}
141
}
124
 
142
 
125
 
143
 
126
static void cursor_up(struct linedb *db, unsigned char *cursorposy) {
144
static void cursor_up(struct linedb *db, unsigned char *cursorposy, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
127
  if (db->cursor->prev != NULL) {
145
  if (db->cursor->prev != NULL) {
128
    db->cursor = db->cursor->prev;
146
    db->cursor = db->cursor->prev;
129
    if (*cursorposy == 0) {
147
    if (*cursorposy == 0) {
130
      db->topscreen = db->cursor;
148
      db->topscreen = db->cursor;
-
 
149
      *uidirtyfrom = 0;
-
 
150
      *uidirtyto = 0xff;
131
    } else {
151
    } else {
132
      *cursorposy -= 1;
152
      *cursorposy -= 1;
133
    }
153
    }
134
  }
154
  }
135
}
155
}
136
 
156
 
137
 
157
 
138
static void cursor_eol(struct linedb *db, unsigned char *cursorposx, unsigned char screenw) {
158
static void cursor_eol(struct linedb *db, unsigned char *cursorposx, unsigned char screenw, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
139
  /* adjust xoffset to make sure eol is visible on screen */
159
  /* adjust xoffset to make sure eol is visible on screen */
-
 
160
  if (db->xoffset > db->cursor->len) {
-
 
161
    db->xoffset = db->cursor->len - 1;
-
 
162
    *uidirtyfrom = 0;
-
 
163
    *uidirtyto = 0xff;
-
 
164
  }
-
 
165
 
140
  if (db->xoffset > db->cursor->len) db->xoffset = db->cursor->len - 1;
166
  if (db->xoffset + screenw - 1 <= db->cursor->len) {
141
  if (db->xoffset + screenw - 1 <= db->cursor->len) db->xoffset = db->cursor->len - screenw + 2;
167
    db->xoffset = db->cursor->len - screenw + 2;
-
 
168
    *uidirtyfrom = 0;
-
 
169
    *uidirtyto = 0xff;
-
 
170
  }
142
  *cursorposx = db->cursor->len - db->xoffset;
171
  *cursorposx = db->cursor->len - db->xoffset;
143
}
172
}
144
 
173
 
145
 
174
 
146
static void cursor_down(struct linedb *db, unsigned char *cursorposy, unsigned char screenh) {
175
static void cursor_down(struct linedb *db, unsigned char *cursorposy, unsigned char screenh, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
147
  if (db->cursor->next != NULL) {
176
  if (db->cursor->next != NULL) {
148
    db->cursor = db->cursor->next;
177
    db->cursor = db->cursor->next;
149
    if (*cursorposy < screenh - 2) {
178
    if (*cursorposy < screenh - 2) {
150
      *cursorposy += 1;
179
      *cursorposy += 1;
151
    } else {
180
    } else {
152
      db->topscreen = db->topscreen->next;
181
      db->topscreen = db->topscreen->next;
-
 
182
      *uidirtyfrom = 0;
-
 
183
      *uidirtyto = 0xff;
153
    }
184
    }
154
  }
185
  }
155
}
186
}
156
 
187
 
157
 
188
 
158
static void cursor_home(struct linedb *db, unsigned char *cursorposx) {
189
static void cursor_home(struct linedb *db, unsigned char *cursorposx, unsigned char *uidirtyfrom, unsigned char *uidirtyto) {
159
  *cursorposx = 0;
190
  *cursorposx = 0;
-
 
191
  if (db->xoffset != 0) {
160
  db->xoffset = 0;
192
    db->xoffset = 0;
-
 
193
    *uidirtyfrom = 0;
-
 
194
    *uidirtyto = 0xff;
-
 
195
  }
161
}
196
}
162
 
197
 
163
 
198
 
164
int main(int argc, char **argv) {
199
int main(int argc, char **argv) {
165
  FILE *fd;
200
  int fd;
166
  const char *fname = NULL;
201
  const char *fname = NULL;
167
  char buff[1024];
202
  char buff[1024];
168
  struct linedb db;
203
  struct linedb db;
169
  unsigned char screenw = 0, screenh = 0;
204
  unsigned char screenw = 0, screenh = 0;
170
  unsigned char cursorposx = 0, cursorposy = 0;
205
  unsigned char cursorposx = 0, cursorposy = 0;
-
 
206
  unsigned char uidirtyfrom = 0, uidirtyto = 0xff; /* make sure to redraw entire UI at first run */
171
 
207
 
172
  bzero(&db, sizeof(db));
208
  bzero(&db, sizeof(db));
173
 
209
 
-
 
210
  svarlang_autoload_nlspath("sved");
-
 
211
 
174
  if ((argc != 2) || (argv[1][0] == '/')) {
212
  if ((argc != 2) || (argv[1][0] == '/')) {
175
    mdr_coutraw_puts("usage: sved file.txt");
213
    mdr_coutraw_puts("usage: sved file.txt");
176
    return(0);
214
    return(0);
177
  }
215
  }
178
 
216
 
179
  fname = argv[1];
217
  fname = argv[1];
180
 
218
 
181
  printf("Loading %s...", fname);
-
 
182
  mdr_coutraw_puts("");
219
  mdr_coutraw_puts("");
183
 
220
 
184
  fd = fopen(fname, "rb");
221
  if (_dos_open(fname, O_RDONLY, &fd) != 0) {
185
  if (fd == NULL) {
-
 
186
    printf("ERROR: failed to open file %s", fname);
222
    mdr_coutraw_puts("Failed to open file:");
187
    mdr_coutraw_puts("");
223
    mdr_coutraw_puts(fname);
188
    return(1);
224
    return(1);
189
  }
225
  }
190
 
226
 
-
 
227
  /* load file */
-
 
228
  {
-
 
229
    unsigned int prevlen = 0, len, llen;
-
 
230
 
-
 
231
    do {
-
 
232
      if (_dos_read(fd, buff + prevlen, sizeof(buff) - prevlen, &len) != 0) break;
-
 
233
      len += prevlen;
-
 
234
 
-
 
235
      /* look for nearest \n and replace with 0*/
-
 
236
      for (llen = 0; buff[llen] != '\n'; llen++) {
191
  while (fgets(buff, sizeof(buff), fd) != NULL) {
237
        if (llen == sizeof(buff)) break;
-
 
238
      }
-
 
239
      buff[llen] = 0;
-
 
240
      if ((llen > 0) && (buff[llen - 1])) buff[llen - 1] = 0; /* trim \r if line ending is cr/lf */
192
    line_add(&db, buff);
241
      line_add(&db, buff);
-
 
242
 
-
 
243
      len -= llen + 1;
-
 
244
      memmove(buff, buff + llen + 1, len);
-
 
245
      prevlen = len;
-
 
246
    } while (len > 0);
-
 
247
 
193
  }
248
  }
-
 
249
 
194
  /* add an empty line at end if not present already */
250
  /* add an empty line at end if not present already */
195
  if (db.cursor->len != 0) line_add(&db, "");
251
  if (db.cursor->len != 0) line_add(&db, "");
196
 
252
 
197
  fclose(fd);
253
  _dos_close(fd);
198
 
254
 
199
  if (mdr_cout_init(&screenw, &screenh)) load_colorscheme();
255
  if (mdr_cout_init(&screenw, &screenh)) load_colorscheme();
200
  ui_basic(screenw, screenh, fname);
256
  ui_basic(screenw, screenh, fname);
201
 
257
 
202
  db_rewind(&db);
258
  db_rewind(&db);
203
 
259
 
204
  for (;;) {
260
  for (;;) {
205
    int k;
261
    int k;
206
 
262
 
207
    check_cursor_not_after_eol(&db, &cursorposx);
263
    check_cursor_not_after_eol(&db, &cursorposx, &uidirtyfrom, &uidirtyto);
208
    mdr_cout_locate(cursorposy, cursorposx);
264
    mdr_cout_locate(cursorposy, cursorposx);
209
 
265
 
-
 
266
    if (uidirtyfrom != 0xff) {
210
    ui_refresh(&db, screenw, screenh);
267
      ui_refresh(&db, screenw, screenh, uidirtyfrom, uidirtyto);
-
 
268
      uidirtyfrom = 0xff;
-
 
269
    }
211
 
270
 
212
    k = keyb_getkey();
271
    k = keyb_getkey();
-
 
272
 
213
    if (k == 0x150) { /* down */
273
    if (k == 0x150) { /* down */
214
      cursor_down(&db, &cursorposy, screenh);
274
      cursor_down(&db, &cursorposy, screenh, &uidirtyfrom, &uidirtyto);
215
 
275
 
216
    } else if (k == 0x148) { /* up */
276
    } else if (k == 0x148) { /* up */
217
      cursor_up(&db, &cursorposy);
277
      cursor_up(&db, &cursorposy, &uidirtyfrom, &uidirtyto);
218
 
278
 
219
    } else if (k == 0x14D) { /* right */
279
    } else if (k == 0x14D) { /* right */
220
      if (db.cursor->len > db.xoffset + cursorposx) {
280
      if (db.cursor->len > db.xoffset + cursorposx) {
221
        if (cursorposx < screenw - 2) {
281
        if (cursorposx < screenw - 2) {
222
          cursorposx++;
282
          cursorposx++;
223
        } else {
283
        } else {
224
          db.xoffset++;
284
          db.xoffset++;
-
 
285
          uidirtyfrom = 0;
-
 
286
          uidirtyto = 0xff;
225
        }
287
        }
226
      } else {
288
      } else {
227
        cursor_down(&db, &cursorposy, screenh);
289
        cursor_down(&db, &cursorposy, screenh, &uidirtyfrom, &uidirtyto);
228
        cursor_home(&db, &cursorposx);
290
        cursor_home(&db, &cursorposx, &uidirtyfrom, &uidirtyto);
229
      }
291
      }
230
 
292
 
231
    } else if (k == 0x14B) { /* left */
293
    } else if (k == 0x14B) { /* left */
232
      if (cursorposx > 0) {
294
      if (cursorposx > 0) {
233
        cursorposx--;
295
        cursorposx--;
234
      } else if (db.xoffset > 0) {
296
      } else if (db.xoffset > 0) {
235
        db.xoffset--;
297
        db.xoffset--;
-
 
298
        uidirtyfrom = 0;
-
 
299
        uidirtyto = 0xff;
236
      } else if (db.cursor->prev != NULL) { /* jump to end of line above */
300
      } else if (db.cursor->prev != NULL) { /* jump to end of line above */
237
        cursor_up(&db, &cursorposy);
301
        cursor_up(&db, &cursorposy, &uidirtyfrom, &uidirtyto);
238
        cursor_eol(&db, &cursorposx, screenw);
302
        cursor_eol(&db, &cursorposx, screenw, &uidirtyfrom, &uidirtyto);
239
      }
303
      }
240
 
304
 
-
 
305
    } else if (k == 0x149) { /* pgup */
-
 
306
      // TODO
-
 
307
 
-
 
308
    } else if (k == 0x151) { /* pgdown */
-
 
309
      // TODO
-
 
310
 
-
 
311
    } else if (k == 0x147) { /* home */
-
 
312
       cursor_home(&db, &cursorposx, &uidirtyfrom, &uidirtyto);
-
 
313
 
-
 
314
    } else if (k == 0x14F) { /* end */
-
 
315
       cursor_eol(&db, &cursorposx, screenw, &uidirtyfrom, &uidirtyto);
-
 
316
 
241
    } else if (k == 0x1B) { /* ESC */
317
    } else if (k == 0x1B) { /* ESC */
242
      break;
318
      break;
243
 
319
 
-
 
320
    } else { /* UNHANDLED KEY - TODO IGNORE THIS IN PRODUCTION RELEASE */
244
    } else {
321
      char buff[4];
-
 
322
      const char *HEX = "0123456789ABCDEF";
-
 
323
      buff[0] = HEX[(k >> 8) & 15];
245
      printf("UNHANDLED KEY 0x%02X", k);
324
      buff[1] = HEX[(k >> 4) & 15];
-
 
325
      buff[2] = HEX[k & 15];
-
 
326
      mdr_cout_str(screenh - 1, 0, "UNHANDLED KEY: 0x", scheme[COL_STATUSBAR1], 17);
-
 
327
      mdr_cout_str(screenh - 1, 17, buff, scheme[COL_STATUSBAR1], 3);
246
      keyb_getkey();
328
      keyb_getkey();
247
      break;
329
      break;
248
    }
330
    }
249
  }
331
  }
250
 
332