EDIT: Modified to load help from file, switched to 100% conio calls for screen

This commit is contained in:
Bobbi Webber-Manners 2020-08-01 00:25:08 -04:00
parent 61c8763ff4
commit 4012deb091

View File

@ -3,8 +3,11 @@
// Bobbi July 2020 // Bobbi July 2020
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Note use my fork of cc65 to get a flashing cursor!! // Note: Use my fork of cc65 to get a flashing cursor!!
// TODO: There is a bug whereby the rowlen[] values seem to get corrupted
// TODO: Add word wrap feature (OA-W ?)
// TODO: Improve insert file feature to not change filename
// TODO: Improve status line, refresh it properly // TODO: Improve status line, refresh it properly
// TODO: Minor bug - can delete too many chars from status line // TODO: Minor bug - can delete too many chars from status line
// TODO: Should be smarter about redrawing when updating selection!!! // TODO: Should be smarter about redrawing when updating selection!!!
@ -31,8 +34,6 @@
#define BACKSPACE 0x08 #define BACKSPACE 0x08
#define CURDOWN 0x0a #define CURDOWN 0x0a
#define RETURN 0x0d #define RETURN 0x0d
#define NORMAL 0x0e
#define INVERSE 0x0f
#define NOMOUSETXT 0x1b #define NOMOUSETXT 0x1b
#define HOME 0x19 #define HOME 0x19
#define CLRLINE 0x1a #define CLRLINE 0x1a
@ -41,13 +42,13 @@
#define CLREOL 0x1d #define CLREOL 0x1d
#define DELETE 0x7f #define DELETE 0x7f
#define BUFSZ (39 * 512) #define BUFSZ (41 * 512) // 20.5KB
char gapbuf[BUFSZ]; char gapbuf[BUFSZ];
char padding = 0; // To null terminate for strstr() char padding = 0; // To null terminate for strstr()
uint16_t gapbegin = 0; uint16_t gapbegin = 0;
uint16_t gapend = BUFSZ - 1; uint16_t gapend = BUFSZ - 1;
uint8_t rowlen[NROWS]; // Number of chars on each row of screen uint8_t rowlen[NROWS]; // Number of chars on each row of screen
char filename[80] = ""; char filename[80] = "";
char userentry[80] = ""; char userentry[80] = "";
@ -87,16 +88,55 @@ char openapple[] = "\x0f\x1b""A\x18\x0e";
*/ */
#define GETPOS() (gapbegin) #define GETPOS() (gapbegin)
/*
* Annoying beep
*/
#pragma code-name (push, "LC")
void beep(void) {
putchar(BELL);
}
#pragma code-name (pop)
/*
* Clear to EOL
*/
#pragma code-name (push, "LC")
void clreol(void) {
uint8_t x = wherex(), y = wherey();
cclear(80 - x);
gotoxy(x, y);
}
#pragma code-name (pop)
/*
* Clear to EOL, wrap to next line
*/
#pragma code-name (push, "LC")
void clreol_wrap(void) {
uint8_t x = wherex();
cclear(80 - x);
gotox(x);
}
#pragma code-name (pop)
/*
* Clear line
*/
#pragma code-name (push, "LC")
void clrline(void) {
uint8_t x = wherex();
gotox(0);
cclear(80);
gotox(x);
}
#pragma code-name (pop)
/* /*
* Put cursor at beginning of PROMPT_ROW * Put cursor at beginning of PROMPT_ROW
*/ */
#pragma code-name (push, "LC") #pragma code-name (push, "LC")
void goto_prompt_row(void) { void goto_prompt_row(void) {
uint8_t i; gotoxy(0, PROMPT_ROW);
putchar(HOME);
for (i = 0; i < PROMPT_ROW; ++i)
putchar(CURDOWN);
gotoxy(1, PROMPT_ROW);
} }
#pragma code-name (pop) #pragma code-name (pop)
@ -113,15 +153,17 @@ uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
char c; char c;
cursor(0); cursor(0);
goto_prompt_row(); goto_prompt_row();
putchar(CLREOL); clreol();
printf("%c%s>%c", INVERSE, prompt, NORMAL); revers(1);
cprintf("%s>", prompt);
revers(0);
gotox(2 + strlen(prompt)); gotox(2 + strlen(prompt));
i = 0; i = 0;
while (1) { while (1) {
c = cgetc(); c = cgetc();
if (is_file && !isalnum(c) && (c != RETURN) && (c != BACKSPACE) && if (is_file && !isalnum(c) && (c != RETURN) && (c != BACKSPACE) &&
(c != DELETE) && (c != ESC) && (c != '.') && (c != '/')) { (c != DELETE) && (c != ESC) && (c != '.') && (c != '/')) {
putchar(BELL); beep();
continue; continue;
} }
switch (c) { switch (c) {
@ -135,7 +177,7 @@ uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
gotox(wherex() - 1); gotox(wherex() - 1);
--i; --i;
} else } else
putchar(BELL); beep();
break; break;
case ESC: case ESC:
userentry[0] = '\0'; userentry[0] = '\0';
@ -151,7 +193,7 @@ uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
done: done:
userentry[i] = '\0'; userentry[i] = '\0';
esc_pressed: esc_pressed:
putchar(CLRLINE); clrline();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
cursor(1); cursor(1);
return i; return i;
@ -166,19 +208,21 @@ char prompt_okay(char *msg) {
char c; char c;
cursor(0); cursor(0);
goto_prompt_row(); goto_prompt_row();
putchar(CLREOL); clreol();
printf("%c%sSure? (y/n)%c", INVERSE, msg, NORMAL); revers(1);
cprintf("%sSure? (y/n)", msg);
revers(0);
while (1) { while (1) {
c = cgetc(); c = cgetc();
if ((c == 'y') || (c == 'Y') || (c == 'n') || (c == 'N')) if ((c == 'y') || (c == 'Y') || (c == 'n') || (c == 'N'))
break; break;
putchar(BELL); beep();
} }
if ((c == 'y') || (c == 'Y')) if ((c == 'y') || (c == 'Y'))
c = 1; c = 1;
else else
c = 0; c = 0;
putchar(CLRLINE); clrline();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
cursor(1); cursor(1);
return c; return c;
@ -192,10 +236,12 @@ char prompt_okay(char *msg) {
void show_error(char *msg) { void show_error(char *msg) {
cursor(0); cursor(0);
goto_prompt_row(); goto_prompt_row();
putchar(BELL); beep();
printf("%c%s [Press Any Key]%c", INVERSE, msg, NORMAL); revers(1);
cprintf("%s [Press Any Key]", msg);
revers(0);
cgetc(); cgetc();
putchar(CLRLINE); clrline();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
cursor(1); cursor(1);
} }
@ -208,7 +254,9 @@ void show_error(char *msg) {
void show_info(char *msg) { void show_info(char *msg) {
cursor(0); cursor(0);
goto_prompt_row(); goto_prompt_row();
printf("%c%s%c", INVERSE, msg, NORMAL); revers(1);
cprintf("%s", msg);
revers(0);
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
cursor(1); cursor(1);
} }
@ -219,6 +267,7 @@ void show_info(char *msg) {
* c - character to insert * c - character to insert
* Returns 0 on success, 1 on failure (insufficient space) * Returns 0 on success, 1 on failure (insufficient space)
*/ */
#pragma code-name (push, "LC")
uint8_t insert_char(char c) { uint8_t insert_char(char c) {
if (FREESPACE()) { if (FREESPACE()) {
gapbuf[gapbegin++] = c; gapbuf[gapbegin++] = c;
@ -226,26 +275,31 @@ uint8_t insert_char(char c) {
} }
return 1; return 1;
} }
#pragma code-name (pop)
/* /*
* Delete the character to the left of the current position * Delete the character to the left of the current position
* Returns 0 on success, 1 on failure (nothing to delete) * Returns 0 on success, 1 on failure (nothing to delete)
*/ */
#pragma code-name (push, "LC")
uint8_t delete_char(void) { uint8_t delete_char(void) {
if (gapbegin == 0) if (gapbegin == 0)
return 1; return 1;
--gapbegin; --gapbegin;
} }
#pragma code-name (pop)
/* /*
* Delete the character to the right of the current position * Delete the character to the right of the current position
* Returns 0 on success, 1 on failure (nothing to delete) * Returns 0 on success, 1 on failure (nothing to delete)
*/ */
#pragma code-name (push, "LC")
uint8_t delete_char_right(void) { uint8_t delete_char_right(void) {
if (gapend == BUFSZ - 1) if (gapend == BUFSZ - 1)
return 1; return 1;
++gapend; ++gapend;
} }
#pragma code-name (pop)
/* /*
* Obtain the next character (to the right of the current position) * Obtain the next character (to the right of the current position)
@ -253,12 +307,14 @@ uint8_t delete_char_right(void) {
* c - character is returned throught this pointer * c - character is returned throught this pointer
* Returns 0 on success, 1 if at end of the buffer. * Returns 0 on success, 1 if at end of the buffer.
*/ */
#pragma code-name (push, "LC")
uint8_t get_char(char *c) { uint8_t get_char(char *c) {
if (gapend == BUFSZ - 1) if (gapend == BUFSZ - 1)
return 1; return 1;
*c = gapbuf[gapbegin++] = gapbuf[++gapend]; *c = gapbuf[gapbegin++] = gapbuf[++gapend];
return 0; return 0;
} }
#pragma code-name (pop)
/* /*
* Move the current position * Move the current position
@ -394,18 +450,20 @@ uint8_t read_char_update_pos(void) {
else else
revers(0); revers(0);
if ((c = gapbuf[pos++]) == EOL) { if ((c = gapbuf[pos++]) == EOL) {
revers(0);
if (do_print) { if (do_print) {
revers(0);
rowlen[row] = col + 1; rowlen[row] = col + 1;
putchar(CLREOL); clreol_wrap();
putchar('\r'); gotox(0);
} }
++row; ++row;
col = 0; col = 0;
return 1; return 1;
} }
if (do_print) if (do_print) {
cputc(c); cputc(c);
revers(0);
}
++col; ++col;
if (do_print) if (do_print)
rowlen[row] = col; rowlen[row] = col;
@ -413,7 +471,6 @@ uint8_t read_char_update_pos(void) {
++row; ++row;
col = 0; col = 0;
} }
revers(0);
return 0; return 0;
} }
@ -429,8 +486,6 @@ void draw_screen(void) {
for (rowsabove = 0; rowsabove < NROWS; ++rowsabove) for (rowsabove = 0; rowsabove < NROWS; ++rowsabove)
rowlen[rowsabove] = 0; rowlen[rowsabove] = 0;
revers(0);
// First we have to scan back to work out where in the buffer to // First we have to scan back to work out where in the buffer to
// start drawing on the screen at the top left. This is at most // start drawing on the screen at the top left. This is at most
// NROWS * NCOLS chars. // NROWS * NCOLS chars.
@ -465,6 +520,7 @@ void draw_screen(void) {
// Finally actually write the text to the screen! // Finally actually write the text to the screen!
videomode(VIDEOMODE_80COL); videomode(VIDEOMODE_80COL);
clrscr(); clrscr();
revers(0);
row = col = 0; row = col = 0;
do_print = 1; do_print = 1;
while (pos < gapbegin) while (pos < gapbegin)
@ -479,19 +535,19 @@ void draw_screen(void) {
read_char_update_pos(); read_char_update_pos();
goto_prompt_row(); goto_prompt_row();
printf("%s-? Help ", openapple);
gotox(10);
revers(1); revers(1);
cprintf("OA-? Help | ");
if (strlen(filename)) { if (strlen(filename)) {
cprintf(" %c File:%s", modified ? '*' : ' ', filename); cprintf(" %c File:%s", modified ? '*' : ' ', filename);
for (startpos = 0; startpos < 62 - strlen(filename); ++startpos) for (startpos = 0; startpos < 60 - strlen(filename); ++startpos)
cputc(' '); cputc(' ');
} else { } else {
cprintf( cprintf(
" File:NONE "); " File:NONE ");
} }
revers(0);
putchar(HOME);
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
cursor(1); cursor(1);
} }
@ -540,19 +596,19 @@ void update_after_delete_char_right(void) {
eol = read_char_update_pos(); eol = read_char_update_pos();
} }
if (is_last_line()) if (is_last_line())
putchar(CLREOL); clreol_wrap();
// If necessary, print rest of screen // If necessary, print rest of screen
if ((gapbuf[gapend] == EOL) || (i == NCOLS - 1)) { if ((gapbuf[gapend] == EOL) || (i == NCOLS - 1)) {
while ((pos < BUFSZ) && (row < NROWS)) while ((pos < BUFSZ) && (row < NROWS))
read_char_update_pos(); read_char_update_pos();
putchar(CLREOL); clreol_wrap();
// Erase the rest of the screen (if any) // Erase the rest of the screen (if any)
for (i = row + 1; i < NROWS; ++i) { for (i = row + 1; i < NROWS; ++i) {
gotoxy(0, i); gotoxy(0, i);
putchar(CLRLINE); clrline();
} }
} }
@ -608,19 +664,19 @@ void update_after_delete_char(void) {
eol = read_char_update_pos(); eol = read_char_update_pos();
} }
if (is_last_line()) if (is_last_line())
putchar(CLREOL); clreol_wrap();
// If necessary, print rest of screen // If necessary, print rest of screen
if ((gapbuf[gapbegin] == EOL) || (i == NCOLS - 1)) { if ((gapbuf[gapbegin] == EOL) || (i == NCOLS - 1)) {
while ((pos < BUFSZ) && (row < NROWS)) while ((pos < BUFSZ) && (row < NROWS))
read_char_update_pos(); read_char_update_pos();
putchar(CLREOL); clreol_wrap();
// Erase the rest of the screen (if any) // Erase the rest of the screen (if any)
for (i = row + 1; i < NROWS; ++i) { for (i = row + 1; i < NROWS; ++i) {
gotoxy(0, i); gotoxy(0, i);
putchar(CLRLINE); clrline();
} }
} }
@ -675,7 +731,7 @@ void cursor_left(void) {
if (gapbegin > 0) if (gapbegin > 0)
gapbuf[gapend--] = gapbuf[--gapbegin]; gapbuf[gapend--] = gapbuf[--gapbegin];
else { else {
putchar(BELL); beep();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
return; return;
} }
@ -683,7 +739,7 @@ void cursor_left(void) {
if (cursrow == 0) { if (cursrow == 0) {
scroll_up(); scroll_up();
if (cursrow == 0) { if (cursrow == 0) {
putchar(BELL); beep();
return; return;
} }
} }
@ -703,7 +759,7 @@ void cursor_right(void) {
if (gapend < BUFSZ - 1) if (gapend < BUFSZ - 1)
gapbuf[gapbegin++] = gapbuf[++gapend]; gapbuf[gapbegin++] = gapbuf[++gapend];
else { else {
putchar(BELL); beep();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
return; return;
} }
@ -730,7 +786,7 @@ uint8_t cursor_up(void) {
if (cursrow == 0) { if (cursrow == 0) {
scroll_up(); scroll_up();
if (cursrow == 0) { if (cursrow == 0) {
putchar(BELL); beep();
gotoxy(curscol, cursrow); gotoxy(curscol, cursrow);
return 1; return 1;
} }
@ -766,7 +822,7 @@ uint8_t cursor_down(void) {
if (gapend < BUFSZ - 1) if (gapend < BUFSZ - 1)
gapbuf[gapbegin++] = gapbuf[++gapend]; gapbuf[gapbegin++] = gapbuf[++gapend];
else { else {
putchar(BELL); beep();
return 1; return 1;
} }
} }
@ -848,36 +904,39 @@ void page_up(void) {
/* /*
* Help screen * Help screen
* EDITHELP.TXT is expected to contain lines of exactly 80 chars
*/ */
#pragma code-name (push, "LC") #pragma code-name (push, "LC")
void help(void) { void help(void) {
FILE *fp = fopen("EDITHELP.TXT", "rb");
uint8_t *p;
char c;
p = (uint8_t*)0xc00e;
*p = 0; // Turn on ALT CHARSET
revers(0); revers(0);
cursor(0); cursor(0);
clrscr(); clrscr();
printf("EDITOR HELP\n\n"); if (!fp) {
printf(" %s-C Copy text (includes cut & paste)\n", openapple); printf("Can't open EDITHELP.TXT\n\n");
printf(" %s-D Delete text\n", openapple); goto done;
printf(" %s-F Find string\n", openapple); }
printf(" %s-L Load file\n", openapple); c = fgetc(fp);
printf(" %s-M Move text (includes cut & paste)\n", openapple); while (!feof(fp)) {
printf(" %s-N Name file\n", openapple); if (c == '@') {
printf(" %s-Q Quit\n", openapple); revers(1);
printf(" %s-R Replace string\n", openapple); cputc('A');
printf(" %s-S Save file\n", openapple); revers(0);
printf(" [Return] End paragraph\n"); } else if ((c != '\r') && (c != '\n'))
printf(" [Delete] Delete char left\n"); cputc(c);
printf(" %s-[Delete] Delete char right\n", openapple); c = fgetc(fp);
printf(" Arrows Move the cursor\n"); }
printf(" %s-Up arrow Page up\n", openapple); fclose(fp);
printf(" %s-Down arrow Page down\n", openapple); done:
printf(" %s-Left arrow Word left\n", openapple); printf("[Press Any Key]");
printf(" %s-Right arrow Word right\n", openapple); p = (uint8_t*)0xc00f;
printf(" %s-< Beginning of line\n", openapple); *p = 0; // Turn off ALT CHARSET
printf(" %s-> End of line\n", openapple);
printf(" [Tab] Go to next tabstop\n");
printf(" %s-1 to %s-9 Beginning of file through end of file\n", openapple, openapple);
printf(" [Press Any Key]");
cgetc(); cgetc();
clrscr();
} }
#pragma code-name (pop) #pragma code-name (pop)
@ -910,7 +969,7 @@ void load_attacher(void) {
*/ */
void save(void) { void save(void) {
if (strlen(filename) == 0) { if (strlen(filename) == 0) {
if (prompt_for_name("Save file", 1) == 255) if (prompt_for_name("File to save", 1) == 255)
return; // If ESC pressed return; // If ESC pressed
if (strlen(userentry) == 0) if (strlen(userentry) == 0)
return; return;
@ -1116,7 +1175,7 @@ int edit(char *fname) {
case 0x80 + 'L': // OA-L "Load" case 0x80 + 'L': // OA-L "Load"
case 0x80 + 'l': case 0x80 + 'l':
++tmp; ++tmp;
if (prompt_for_name((tmp == 0 ? "Insert file" : "Load file"), 1) == 255) if (prompt_for_name((tmp == 0 ? "File to insert" : "File to load"), 1) == 255)
break; // ESC pressed break; // ESC pressed
if (strlen(userentry) == 0) if (strlen(userentry) == 0)
break; break;