From 2e8910f901039813a668c9917782350aee8d5099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Sat, 2 Nov 2024 14:05:12 -0400 Subject: [PATCH] Initial Prestel support. Basic Prestel support based on the "Prestel Terminal Specification" Issue 2 by the Post Office. Known issues: Modifying an existing line does not update the row after it. Double height is not supported. Keyboard mapping kinda sucks (looking at you #/Return). Concealed is always shown. Remote programming sequences aren't supported. There appears to be something wrong with the End of the Line title and menu screens, but maybe nelgin did them wrong. --- src/conio/allfonts.c | 261 ++++++++++++++++++++- src/conio/ciolib.adoc | 6 + src/conio/ciolib.h | 8 +- src/conio/cterm.c | 460 ++++++++++++++++++++++++++++++++----- src/conio/cterm.h | 7 + src/conio/utf8_codepages.c | 120 ++++++++++ src/conio/utf8_codepages.h | 1 + src/conio/vidmodes.c | 42 ++-- src/conio/vidmodes.h | 5 +- src/syncterm/bbslist.c | 21 +- src/syncterm/bbslist.h | 2 + src/syncterm/syncterm.c | 4 + src/syncterm/term.c | 45 ++++ 13 files changed, 900 insertions(+), 82 deletions(-) diff --git a/src/conio/allfonts.c b/src/conio/allfonts.c index f2d6a5452f..40819226d8 100644 --- a/src/conio/allfonts.c +++ b/src/conio/allfonts.c @@ -46,7 +46,8 @@ CIOLIBEXPORT struct conio_font_data_struct conio_fontdata[257] = { {NULL, NULL, NULL , "MicroKnight Plus (Amiga)", CIOLIB_ISO_8859_1}, {NULL, NULL, NULL, "Topaz Plus (Amiga)", CIOLIB_ISO_8859_1}, {NULL, NULL, NULL, "MicroKnight (Amiga)", CIOLIB_ISO_8859_1}, - {NULL, NULL, NULL, "Topaz (Amiga)", CIOLIB_ISO_8859_1} + {NULL, NULL, NULL, "Topaz (Amiga)", CIOLIB_ISO_8859_1}, + {NULL, NULL, NULL, "Prestel (8x16)", CIOLIB_PRESETL}, }; #else CIOLIBEXPORT struct conio_font_data_struct conio_fontdata[257] = { @@ -23607,7 +23608,263 @@ CIOLIBEXPORT struct conio_font_data_struct conio_fontdata[257] = { "\xf0\x60\x60\x7c\x66\x66\x66\x7c\x60\x60\xf0\x00\x00\x00" "\x66\x66\x00\x66\x66\x66\x66\x3c\x18\x18\x70\x00\x00\x00" , NULL, "Topaz (Amiga)", CIOLIB_ISO_8859_1} - ,{NULL, NULL, NULL, NULL, CIOLIB_CP437} + ,{"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x18\x3c\x3c\x3c\x18\x18\x18\x00\x18\x18\x00\x00\x00\x00" + "\x00\x66\x66\x66\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x38\x6c\x64\x60\x60\xf0\x60\x60\xe6\xfc\x00\x00\x00\x00" + "\x18\x18\x7c\xc6\xc2\xc0\x7c\x06\x06\x86\xc6\x7c\x18\x18\x00\x00" + "\x00\x00\x00\x00\xc2\xc6\x0c\x18\x30\x60\xc6\x86\x00\x00\x00\x00" + "\x00\x00\x38\x6c\x6c\x38\x76\xdc\xcc\xcc\xcc\x76\x00\x00\x00\x00" + "\x00\x30\x30\x30\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x0c\x18\x30\x30\x30\x30\x30\x30\x18\x0c\x00\x00\x00\x00" + "\x00\x00\x30\x18\x0c\x0c\x0c\x0c\x0c\x0c\x18\x30\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x66\x3c\xff\x3c\x66\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x18\x18\x7e\x18\x18\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x18\x30\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x00\x00\x00\x00" + "\x00\x00\x00\x00\x02\x06\x0c\x18\x30\x60\xc0\x80\x00\x00\x00\x00" + "\x00\x00\x3c\x66\xc3\xc3\xdb\xdb\xc3\xc3\x66\x3c\x00\x00\x00\x00" + "\x00\x00\x18\x38\x78\x18\x18\x18\x18\x18\x18\x7e\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\x06\x0c\x18\x30\x60\xc0\xc6\xfe\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\x06\x06\x3c\x06\x06\x06\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x0c\x1c\x3c\x6c\xcc\xfe\x0c\x0c\x0c\x1e\x00\x00\x00\x00" + "\x00\x00\xfe\xc0\xc0\xc0\xfc\x06\x06\x06\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x38\x60\xc0\xc0\xfc\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\xfe\xc6\x06\x06\x0c\x18\x30\x30\x30\x30\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\xc6\x7c\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\xc6\x7e\x06\x06\x06\x0c\x78\x00\x00\x00\x00" + "\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x18\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x18\x30\x00\x00\x00\x00" + "\x00\x00\x00\x06\x0c\x18\x30\x60\x30\x18\x0c\x06\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7e\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x60\x30\x18\x0c\x06\x0c\x18\x30\x60\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\x0c\x18\x18\x18\x00\x18\x18\x00\x00\x00\x00" + "\x00\x00\x00\x7c\xc6\xc6\xde\xde\xde\xdc\xc0\x7c\x00\x00\x00\x00" + "\x00\x00\x10\x38\x6c\xc6\xc6\xfe\xc6\xc6\xc6\xc6\x00\x00\x00\x00" + "\x00\x00\xfc\x66\x66\x66\x7c\x66\x66\x66\x66\xfc\x00\x00\x00\x00" + "\x00\x00\x3c\x66\xc2\xc0\xc0\xc0\xc0\xc2\x66\x3c\x00\x00\x00\x00" + "\x00\x00\xf8\x6c\x66\x66\x66\x66\x66\x66\x6c\xf8\x00\x00\x00\x00" + "\x00\x00\xfe\x66\x62\x68\x78\x68\x60\x62\x66\xfe\x00\x00\x00\x00" + "\x00\x00\xfe\x66\x62\x68\x78\x68\x60\x60\x60\xf0\x00\x00\x00\x00" + "\x00\x00\x3c\x66\xc2\xc0\xc0\xde\xc6\xc6\x66\x3a\x00\x00\x00\x00" + "\x00\x00\xc6\xc6\xc6\xc6\xfe\xc6\xc6\xc6\xc6\xc6\x00\x00\x00\x00" + "\x00\x00\x3c\x18\x18\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00" + "\x00\x00\x1e\x0c\x0c\x0c\x0c\x0c\xcc\xcc\xcc\x78\x00\x00\x00\x00" + "\x00\x00\xe6\x66\x66\x6c\x78\x78\x6c\x66\x66\xe6\x00\x00\x00\x00" + "\x00\x00\xf0\x60\x60\x60\x60\x60\x60\x62\x66\xfe\x00\x00\x00\x00" + "\x00\x00\xc3\xe7\xff\xff\xdb\xc3\xc3\xc3\xc3\xc3\x00\x00\x00\x00" + "\x00\x00\xc6\xe6\xf6\xfe\xde\xce\xc6\xc6\xc6\xc6\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\xfc\x66\x66\x66\x7c\x60\x60\x60\x60\xf0\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\xc6\xd6\xde\x7c\x0c\x0e\x00\x00" + "\x00\x00\xfc\x66\x66\x66\x7c\x6c\x66\x66\x66\xe6\x00\x00\x00\x00" + "\x00\x00\x7c\xc6\xc6\x60\x38\x0c\x06\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\xff\xdb\x99\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00" + "\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\xc3\xc3\xc3\xc3\xc3\xc3\xc3\x66\x3c\x18\x00\x00\x00\x00" + "\x00\x00\xc3\xc3\xc3\xc3\xc3\xdb\xdb\xff\x66\x66\x00\x00\x00\x00" + "\x00\x00\xc3\xc3\x66\x3c\x18\x18\x3c\x66\xc3\xc3\x00\x00\x00\x00" + "\x00\x00\xc3\xc3\xc3\x66\x3c\x18\x18\x18\x18\x3c\x00\x00\x00\x00" + "\x00\x00\xff\xc3\x86\x0c\x18\x30\x60\xc1\xc3\xff\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x30\x60\xfe\x60\x30\x00\x00\x00\x00\x00\x00" + "\x00\xc0\xc0\xc2\xc6\xcc\x18\x30\x60\xce\x9b\x06\x0c\x1f\x00\x00" + "\x00\x00\x00\x00\x00\x18\x0c\xfe\x0c\x18\x00\x00\x00\x00\x00\x00" + "\x00\x00\x18\x3c\x7e\x18\x18\x18\x18\x18\x18\x18\x00\x00\x00\x00" + "\x00\x00\x00\x6c\x6c\xfe\x6c\x6c\x6c\xfe\x6c\x6c\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x78\x0c\x7c\xcc\xcc\xcc\x76\x00\x00\x00\x00" + "\x00\x00\xe0\x60\x60\x78\x6c\x66\x66\x66\x66\x7c\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7c\xc6\xc0\xc0\xc0\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x1c\x0c\x0c\x3c\x6c\xcc\xcc\xcc\xcc\x76\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7c\xc6\xfe\xc0\xc0\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x38\x6c\x64\x60\xf0\x60\x60\x60\x60\xf0\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x76\xcc\xcc\xcc\xcc\xcc\x7c\x0c\xcc\x78\x00" + "\x00\x00\xe0\x60\x60\x6c\x76\x66\x66\x66\x66\xe6\x00\x00\x00\x00" + "\x00\x00\x18\x18\x00\x38\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00" + "\x00\x00\x06\x06\x00\x0e\x06\x06\x06\x06\x06\x06\x66\x66\x3c\x00" + "\x00\x00\xe0\x60\x60\x66\x6c\x78\x78\x6c\x66\xe6\x00\x00\x00\x00" + "\x00\x00\x38\x18\x18\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xe6\xff\xdb\xdb\xdb\xdb\xdb\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xdc\x66\x66\x66\x66\x66\x66\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xdc\x66\x66\x66\x66\x66\x7c\x60\x60\xf0\x00" + "\x00\x00\x00\x00\x00\x76\xcc\xcc\xcc\xcc\xcc\x7c\x0c\x0c\x1e\x00" + "\x00\x00\x00\x00\x00\xdc\x76\x66\x60\x60\x60\xf0\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7c\xc6\x60\x38\x0c\xc6\x7c\x00\x00\x00\x00" + "\x00\x00\x10\x30\x30\xfc\x30\x30\x30\x30\x36\x1c\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\x76\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xc3\xc3\xc3\xc3\x66\x3c\x18\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xc3\xc3\xc3\xdb\xdb\xff\x66\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xc3\x66\x3c\x18\x3c\x66\xc3\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6\x7e\x06\x0c\xf8\x00" + "\x00\x00\x00\x00\x00\xfe\xcc\x18\x30\x60\xc6\xfe\x00\x00\x00\x00" + "\x00\xc0\xc0\xc2\xc6\xcc\x18\x30\x66\xce\x96\x3e\x06\x06\x00\x00" + "\x00\x00\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x00\x00\x00\x00" + "\x00\xe0\x30\xe2\x36\xec\x18\x30\x66\xce\x96\x3e\x06\x06\x00\x00" + "\x00\x00\x00\x00\x10\x00\x00\xfe\x00\x00\x10\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00" + "\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00" + "\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00" + "\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00" + "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00" + "\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00" + "\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0" + "\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0" + "\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0" + "\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0" + "\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" + "\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" + "\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" + "\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" + "\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0" + "\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0" + "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0" + "\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0" + "\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0" + "\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f" + "\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f" + "\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f" + "\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f" + "\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f" + "\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f" + "\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f" + "\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f" + "\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" + "\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" + "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" + "\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f" + "\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f" + "\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff" + "\xf0\xf0\xf0\xf0\xf0\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff" + "\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff" + "\x00\x00\x00\x00\x00\xf0\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff" + "\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff" + "\x0f\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff" + "\x00\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff" + "\xf0\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff" + "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xf0\xf0\xf0\xf0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x70\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00" + "\x70\x70\x70\x70\x00\x70\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00" + "\x07\x07\x07\x07\x00\x70\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00" + "\x77\x77\x77\x77\x00\x70\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x07\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00" + "\x70\x70\x70\x70\x00\x07\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00" + "\x07\x07\x07\x07\x00\x07\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00" + "\x77\x77\x77\x77\x00\x07\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x77\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00" + "\x70\x70\x70\x70\x00\x77\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00" + "\x07\x07\x07\x07\x00\x77\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00" + "\x77\x77\x77\x77\x00\x77\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x70\x70\x70\x00" + "\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x70\x70\x70\x70\x00" + "\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00\x00\x70\x70\x70\x70\x00" + "\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00\x00\x70\x70\x70\x70\x00" + "\x00\x00\x00\x00\x00\x70\x70\x70\x70\x70\x00\x70\x70\x70\x70\x00" + "\x70\x70\x70\x70\x00\x70\x70\x70\x70\x70\x00\x70\x70\x70\x70\x00" + "\x07\x07\x07\x07\x00\x70\x70\x70\x70\x70\x00\x70\x70\x70\x70\x00" + "\x77\x77\x77\x77\x00\x70\x70\x70\x70\x70\x00\x70\x70\x70\x70\x00" + "\x00\x00\x00\x00\x00\x07\x07\x07\x07\x07\x00\x70\x70\x70\x70\x00" + "\x70\x70\x70\x70\x00\x07\x07\x07\x07\x07\x00\x70\x70\x70\x70\x00" + "\x07\x07\x07\x07\x00\x07\x07\x07\x07\x07\x00\x70\x70\x70\x70\x00" + "\x77\x77\x77\x77\x00\x07\x07\x07\x07\x07\x00\x70\x70\x70\x70\x00" + "\x00\x00\x00\x00\x00\x77\x77\x77\x77\x77\x00\x70\x70\x70\x70\x00" + "\x70\x70\x70\x70\x00\x77\x77\x77\x77\x77\x00\x70\x70\x70\x70\x00" + "\x07\x07\x07\x07\x00\x77\x77\x77\x77\x77\x00\x70\x70\x70\x70\x00" + "\x77\x77\x77\x77\x00\x77\x77\x77\x77\x77\x00\x70\x70\x70\x70\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x07\x07\x07\x00" + "\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x07\x07\x07\x07\x00" + "\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00\x00\x07\x07\x07\x07\x00" + "\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00\x00\x07\x07\x07\x07\x00" + "\x00\x00\x00\x00\x00\x70\x70\x70\x70\x70\x00\x07\x07\x07\x07\x00" + "\x70\x70\x70\x70\x00\x70\x70\x70\x70\x70\x00\x07\x07\x07\x07\x00" + "\x07\x07\x07\x07\x00\x70\x70\x70\x70\x70\x00\x07\x07\x07\x07\x00" + "\x77\x77\x77\x77\x00\x70\x70\x70\x70\x70\x00\x07\x07\x07\x07\x00" + "\x00\x00\x00\x00\x00\x07\x07\x07\x07\x07\x00\x07\x07\x07\x07\x00" + "\x70\x70\x70\x70\x00\x07\x07\x07\x07\x07\x00\x07\x07\x07\x07\x00" + "\x07\x07\x07\x07\x00\x07\x07\x07\x07\x07\x00\x07\x07\x07\x07\x00" + "\x77\x77\x77\x77\x00\x07\x07\x07\x07\x07\x00\x07\x07\x07\x07\x00" + "\x00\x00\x00\x00\x00\x77\x77\x77\x77\x77\x00\x07\x07\x07\x07\x00" + "\x70\x70\x70\x70\x00\x77\x77\x77\x77\x77\x00\x07\x07\x07\x07\x00" + "\x07\x07\x07\x07\x00\x77\x77\x77\x77\x77\x00\x07\x07\x07\x07\x00" + "\x77\x77\x77\x77\x00\x77\x77\x77\x77\x77\x00\x07\x07\x07\x07\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x77\x77\x77\x00" + "\x70\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x77\x77\x77\x77\x00" + "\x07\x07\x07\x07\x00\x00\x00\x00\x00\x00\x00\x77\x77\x77\x77\x00" + "\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00\x00\x77\x77\x77\x77\x00" + "\x00\x00\x00\x00\x00\x70\x70\x70\x70\x70\x00\x77\x77\x77\x77\x00" + "\x70\x70\x70\x70\x00\x70\x70\x70\x70\x70\x00\x77\x77\x77\x77\x00" + "\x07\x07\x07\x07\x00\x70\x70\x70\x70\x70\x00\x77\x77\x77\x77\x00" + "\x77\x77\x77\x77\x00\x70\x70\x70\x70\x70\x00\x77\x77\x77\x77\x00" + "\x00\x00\x00\x00\x00\x07\x07\x07\x07\x07\x00\x77\x77\x77\x77\x00" + "\x70\x70\x70\x70\x00\x07\x07\x07\x07\x07\x00\x77\x77\x77\x77\x00" + "\x07\x07\x07\x07\x00\x07\x07\x07\x07\x07\x00\x77\x77\x77\x77\x00" + "\x77\x77\x77\x77\x00\x07\x07\x07\x07\x07\x00\x77\x77\x77\x77\x00" + "\x00\x00\x00\x00\x00\x77\x77\x77\x77\x77\x00\x77\x77\x77\x77\x00" + "\x70\x70\x70\x70\x00\x77\x77\x77\x77\x77\x00\x77\x77\x77\x77\x00" + "\x07\x07\x07\x07\x00\x77\x77\x77\x77\x77\x00\x77\x77\x77\x77\x00" + "\x77\x77\x77\x77\x00\x77\x77\x77\x77\x77\x00\x77\x77\x77\x77\x00" + , NULL, NULL, "Prestel", CIOLIB_PRESTEL} ,{NULL, NULL, NULL, NULL, CIOLIB_CP437} ,{NULL, NULL, NULL, NULL, CIOLIB_CP437} ,{NULL, NULL, NULL, NULL, CIOLIB_CP437} diff --git a/src/conio/ciolib.adoc b/src/conio/ciolib.adoc index 8df6bfe3c7..cb4de0ce98 100644 --- a/src/conio/ciolib.adoc +++ b/src/conio/ciolib.adoc @@ -455,4 +455,10 @@ every size. The following table summarizes the available fonts. |√ | |ISO_8859_1 + +|Prestel +|√ +| +| +|ISO_8859_1 |=== diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h index 5741d684d3..17fce4e2c1 100644 --- a/src/conio/ciolib.h +++ b/src/conio/ciolib.h @@ -90,8 +90,8 @@ enum { ,CYAN ,RED ,MAGENTA - ,BROWN - ,LIGHTGRAY + ,BROWN + ,LIGHTGRAY ,DARKGRAY ,LIGHTBLUE ,LIGHTGREEN @@ -203,6 +203,8 @@ enum text_modes VESA_132X50 = 206, VESA_132X60 = 196, + PRESTEL_40X24 = 254, + /* Custom Mode */ CIOLIB_MODE_CUSTOM = 255, // Last mode... if it's over 255, text_info can't hold it. }; @@ -290,7 +292,7 @@ struct ciolib_screen { uint32_t palette[16]; }; -#define CONIO_FIRST_FREE_FONT 43 +#define CONIO_FIRST_FREE_FONT 44 typedef struct { int mode; diff --git a/src/conio/cterm.c b/src/conio/cterm.c index f8edc0bd4a..91e5cfb5d4 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -784,12 +784,213 @@ setwindow(struct cterminal *cterm) WINDOW(col, row, max_col, max_row); } +static void +set_attr(struct cterminal *cterm, unsigned char colour, bool bg) +{ + if (bg) { + cterm->attr &= 0x8F; + cterm->attr |= ((colour & 0x07) << 4); + } + else { + cterm->attr &= 0xF8; + cterm->attr |= (colour & 0x07); + } + attr2palette(cterm->attr, bg ? NULL : &cterm->fg_color, bg ? &cterm->bg_color : NULL); + if (bg) + FREE_AND_NULL(cterm->bg_tc_str); + else + FREE_AND_NULL(cterm->fg_tc_str); +} + +static void +set_fgattr(struct cterminal *cterm, unsigned char colour) +{ + set_attr(cterm, colour, false ^ cterm->negative); +} + +static void +set_bgattr(struct cterminal *cterm, unsigned char colour) +{ + set_attr(cterm, colour, true ^ cterm->negative); +} + +static void +prestel_new_line(struct cterminal *cterm) +{ + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL | CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT | CTERM_EXTATTR_PRESTEL_HOLD | CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_SEPARATED); + cterm->attr = 7; + attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color); + cterm->prestel_last_mosaic = 32; + TEXTATTR(cterm->attr); + setcolour(cterm->fg_color, cterm->bg_color); +} + +static void +prestel_apply_ctrl(struct cterminal *cterm, uint8_t ch) +{ + switch(ch) { + case 64: // Alphanumeric Black + set_fgattr(cterm, BLACK); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 65: // Alphanumeric Red + set_fgattr(cterm, RED); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 66: // Alphanumeric Green + set_fgattr(cterm, GREEN); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 67: // Alphanumeric Yellow + set_fgattr(cterm, BROWN); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 68: // Alphanumeric Blue + set_fgattr(cterm, BLUE); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 69: // Alphanumeric Magenta + set_fgattr(cterm, MAGENTA); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 70: // Alphanumeric Cyan + set_fgattr(cterm, CYAN); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 71: // Alphanumeric White + set_fgattr(cterm, LIGHTGRAY); + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC); + cterm->prestel_last_mosaic = 32; + break; + case 72: // Flash + cterm->attr |= 0x80; + attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color); + break; + case 73: // Steady + cterm->attr &= 0x7f; + attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color); + break; + case 76: // Normal Height + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT); + cterm->prestel_last_mosaic = 32; + break; + case 77: // Double Height + cterm->extattr |= CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT; + cterm->prestel_last_mosaic = 32; + break; + case 80: // Mosaic Black + set_fgattr(cterm, BLACK); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 81: // Mosaic Red + set_fgattr(cterm, RED); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 82: // Mosaic Green + set_fgattr(cterm, GREEN); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 83: // Mosaic Yellow + set_fgattr(cterm, BROWN); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 84: // Mosaic Blue + set_fgattr(cterm, BLUE); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 85: // Mosaic Magenta + set_fgattr(cterm, MAGENTA); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 86: // Mosaic Cyan + set_fgattr(cterm, CYAN); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 87: // Mosaic White + set_fgattr(cterm, LIGHTGRAY); + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + cterm->prestel_last_mosaic = 32; + break; + case 88: // Conceal Display + cterm->attr |= 0x08; + cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC; + break; + case 89: // Contiguous Mosaics + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_SEPARATED); + break; + case 90: // Separated Mosaics + cterm->extattr |= CTERM_EXTATTR_PRESTEL_SEPARATED; + break; + case 92: // Black Background + set_bgattr(cterm, BLACK); + break; + case 93: // New Background + set_bgattr(cterm, cterm->attr & 0x07); + break; + case 94: // Hold Mosaics + cterm->extattr |= CTERM_EXTATTR_PRESTEL_HOLD; + break; + case 95: // Release Mosaics + cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_HOLD); + break; + } + TEXTATTR(cterm->attr); + setcolour(cterm->fg_color, cterm->bg_color); +} + +static void +prestel_get_state(struct cterminal *cterm) +{ + struct vmem_cell *line; + int sx, sy; + int tx, ty; + + SCR_XY(&sx, &sy); + TERM_XY(&tx, &ty); + line = malloc(sizeof(*line) * tx); + prestel_new_line(cterm); + if (tx > 1) { + vmem_gettext(cterm->x, sy, cterm->x + tx - 2, sy, line); + for (int i = 0; i < (tx - 1); i++) { + uint8_t ch = line[i].ch; + if (line[i].fg & 0x7F000000) { + ch = (line[i].fg & 0x7F000000) >> 24; + prestel_apply_ctrl(cterm, ch); + } + else { + if (ch >= 128) { + cterm->prestel_last_mosaic = ch; + if (ch >= 192) + cterm->prestel_last_mosaic -= 64; + } + } + } + } + free(line); +} + void cterm_gotoxy(struct cterminal *cterm, int x, int y) { coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_CURR, &x, &y); GOTOXY(x, y); ABS_XY(&cterm->xpos, &cterm->ypos); + if (cterm->emulation == CTERM_EMULATION_PRESTEL) + prestel_get_state(cterm); } static void @@ -2317,6 +2518,14 @@ adjust_currpos(struct cterminal *cterm, int xadj, int yadj, int scroll) ty = TERM_MINX; else ty += yadj; + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + while (ty > TERM_MAXY) { + ty -= TERM_MAXY; + } + while (ty < TERM_MINY) { + ty += TERM_MAXY; + } + } if (scroll) { while(ty > TERM_MAXY) { cterm_scrollup(cterm); @@ -2364,6 +2573,8 @@ adjust_currpos(struct cterminal *cterm, int xadj, int yadj, int scroll) if (ty < cterm->top_margin && y >= cterm->top_margin) ty = cterm->top_margin; GOTOXY(tx, ty); + if (cterm->emulation == CTERM_EMULATION_PRESTEL) + prestel_get_state(cterm); } static int @@ -2435,36 +2646,6 @@ set_negative(struct cterminal *cterm, bool on) } } -static void -set_attr(struct cterminal *cterm, unsigned char colour, bool bg) -{ - if (bg) { - cterm->attr &= 0x8F; - cterm->attr |= ((colour & 0x07) << 4); - } - else { - cterm->attr &= 0xF8; - cterm->attr |= (colour & 0x07); - } - attr2palette(cterm->attr, bg ? NULL : &cterm->fg_color, bg ? &cterm->bg_color : NULL); - if (bg) - FREE_AND_NULL(cterm->bg_tc_str); - else - FREE_AND_NULL(cterm->fg_tc_str); -} - -static void -set_fgattr(struct cterminal *cterm, unsigned char colour) -{ - set_attr(cterm, colour, false ^ cterm->negative); -} - -static void -set_bgattr(struct cterminal *cterm, unsigned char colour) -{ - set_attr(cterm, colour, true ^ cterm->negative); -} - static void set_bright_fg(struct cterminal *cterm, unsigned char colour, int flags) { @@ -4699,6 +4880,10 @@ struct cterminal* cterm_init(int height, int width, int xpos, int ypos, int back sem_init(&cterm->playnote_thread_terminated,0,0); _beginthread(playnote_thread, 0, cterm); } + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + cterm->cursor = _NOCURSOR; + SETCURSORTYPE(cterm->cursor); + } return cterm; } @@ -4751,12 +4936,25 @@ advance_char(struct cterminal *cterm, int *x, int *y, int move) GOTOXY(*x, *y); } else if(*y == bm && (*x == rm || *x == CURR_MAXX)) { - cond_scrollup(cterm); - move = 1; - *x = lm; + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + *y = cterm->top_margin; + move = 1; + *x = lm; + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + prestel_new_line(cterm); + } + } + else { + cond_scrollup(cterm); + move = 1; + *x = lm; + } } else { if(*x == rm || *x == CURR_MAXX) { + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + prestel_new_line(cterm); + } *x=lm; if (*y < CURR_MAXY) (*y)++; @@ -5014,6 +5212,48 @@ static void parse_macro_intro(struct cterminal *cterm) #define uctputs(c, p) ctputs(c, (char *)p) #define ustrcat(b, s) strcat((char *)b, (const char *)s) +static void +prestel_move(struct cterminal *cterm, int xadj, int yadj) +{ + int tx, ty; + + TERM_XY(&tx, &ty); + tx += xadj; + ty += yadj; + // First, fix up x... + while (tx < cterm->left_margin) { + ty--; + tx += TERM_MAXX; + } + while (tx > cterm->right_margin) { + ty++; + tx -= TERM_MAXX; + } + // Now fix up y + while (ty < cterm->top_margin) { + ty += TERM_MAXY; + } + while (ty > cterm->bottom_margin) { + ty -= TERM_MAXY; + } + GOTOXY(tx, ty); + prestel_get_state(cterm); +} + +static void prestel_fix_line(struct cterminal *cterm, int y) +{ + int sy = y; + int sx = 1; + int ex = 1; + struct vmem_cell *line; + + coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_SCREEN, &sy, &sx); + ex = sx + TERM_MAXX - 1; + line = malloc(sizeof(*line) * (ex - sx + 1)); + vmem_gettext(sx, sy, ex, sy, line); + free(line); +} + CIOLIBEXPORT char* cterm_write(struct cterminal * cterm, const void *vbuf, int buflen, char *retbuf, size_t retsize, int *speed) { const unsigned char *buf = (unsigned char *)vbuf; @@ -5079,6 +5319,8 @@ CIOLIBEXPORT char* cterm_write(struct cterminal * cterm, const void *vbuf, int b if(cterm->log==CTERM_LOG_RAW && cterm->logfile != NULL) fwrite(buf, buflen, 1, cterm->logfile); prn[0]=0; + if (cterm->emulation == CTERM_EMULATION_PRESTEL) + prestel_get_state(cterm); for(j=0;j<buflen;j++) { if(ustrlen(prn) >= sizeof(prn)-sizeof(cterm->escbuf)) { uctputs(cterm, prn); @@ -5218,27 +5460,51 @@ CIOLIBEXPORT char* cterm_write(struct cterminal * cterm, const void *vbuf, int b } else if(cterm->sequence) { ustrcat(cterm->escbuf,ch); - switch(legal_sequence(cterm->escbuf, sizeof(cterm->escbuf)-1)) { - case SEQ_BROKEN: - /* Broken sequence detected */ - ustrcat(prn,"\033"); - ustrcat(prn,cterm->escbuf); - cterm->escbuf[0]=0; - cterm->sequence=0; - if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ - if(prn[0]) /* Don't display the ESC */ - prn[ustrlen(prn)-1]=0; - uctputs(cterm, prn); - prn[0]=0; - cterm->sequence=1; - } - break; - case SEQ_INCOMPLETE: - break; - case SEQ_COMPLETE: - do_ansi(cterm, retbuf, retsize, speed, lastch); - lastch = 0; - break; + if (cterm->emulation == CTERM_EMULATION_PRESTEL) { + prestel_apply_ctrl(cterm, ch[0]); + cterm->escbuf[0]=0; + cterm->sequence=0; + if (cterm->extattr & CTERM_EXTATTR_PRESTEL_HOLD) { + tmpvc[0].ch = cterm->prestel_last_mosaic; + if ((tmpvc[0].ch >= 128) && (cterm->extattr & CTERM_EXTATTR_PRESTEL_SEPARATED)) + tmpvc[0].ch += 64; + } + else { + tmpvc[0].ch = ch[0] - 64; + } + tmpvc[0].legacy_attr=cterm->attr; + tmpvc[0].fg = cterm->fg_color | (ch[0] << 24); + tmpvc[0].bg = cterm->bg_color; + tmpvc[0].font = ciolib_attrfont(cterm->attr); + SCR_XY(&sx, &sy); + vmem_puttext(sx, sy, sx, sy, tmpvc); + ch[1]=0; + CURR_XY(&x, &y); + advance_char(cterm, &x, &y, 1); + } + else { + switch(legal_sequence(cterm->escbuf, sizeof(cterm->escbuf)-1)) { + case SEQ_BROKEN: + /* Broken sequence detected */ + ustrcat(prn,"\033"); + ustrcat(prn,cterm->escbuf); + cterm->escbuf[0]=0; + cterm->sequence=0; + if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ + if(prn[0]) /* Don't display the ESC */ + prn[ustrlen(prn)-1]=0; + uctputs(cterm, prn); + prn[0]=0; + cterm->sequence=1; + } + break; + case SEQ_INCOMPLETE: + break; + case SEQ_COMPLETE: + do_ansi(cterm, retbuf, retsize, speed, lastch); + lastch = 0; + break; + } } } else if (cterm->music) { @@ -5711,6 +5977,92 @@ CIOLIBEXPORT char* cterm_write(struct cterminal * cterm, const void *vbuf, int b break; } } + else if(cterm->emulation == CTERM_EMULATION_PRESTEL) { + switch(buf[j]) { + case 0: // NUL + uctputs(cterm, prn); + prn[0]=0; + break; + case 5: // ENQ + // Send memory 1 + if(strlen(retbuf) + 10 < retsize) + // TODO: Use the memories... + strcat(retbuf, "0000000000"); + break; + case 8: // APB (Active Position Packward) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + prestel_move(cterm, -1, 0); + break; + case 9: // APF (Active Position Forward) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + prestel_move(cterm, 1, 0); + break; + case 10: // APD (Active Position Down) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + prestel_move(cterm, 0, 1); + break; + case 11: // APU (Active Position Up) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + prestel_move(cterm, 0, -1); + break; + case 12: // CS (Clear Screen) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + prestel_new_line(cterm); + cterm_clearscreen(cterm, (char)cterm->attr); + GOTOXY(CURR_MINX, CURR_MINY); + break; + case 17: // Cursor on + cterm->cursor=_NORMALCURSOR; + SETCURSORTYPE(cterm->cursor); + break; + case 20: // Cursor off + cterm->cursor=_NOCURSOR; + SETCURSORTYPE(cterm->cursor); + break; + case 27: // ESC + uctputs(cterm, prn); + prn[0]=0; + cterm->sequence=1; + break; + case 30: // APH (Active Position Home) + lastch = 0; + uctputs(cterm, prn); + prn[0]=0; + GOTOXY(CURR_MINX, CURR_MINY); + prestel_new_line(cterm); + break; + default: + if (buf[j] == 13 || buf[j] == 10 || (buf[j] >= 32 && buf[j] <= 127)) { + if (cterm->extattr & CTERM_EXTATTR_PRESTEL_MOSAIC) { + if (buf[j] < 64 && buf[j] >= 32) + ch[0] = buf[j] + 96; + else if (buf[j] >= 96 && buf[j] < 128) + ch[0] = buf[j] + 64; + else + ch[0] = buf[j]; + if (ch[0] >= 128) + cterm->prestel_last_mosaic = ch[0]; + if (cterm->extattr & CTERM_EXTATTR_PRESTEL_SEPARATED) { + if (ch[0] >= 128) + ch[0] += 64; + } + } + else + lastch = ch[0]; + ustrcat(prn,ch); + } + } + } else { /* ANSI-BBS */ if(cterm->doorway_char) { uctputs(cterm, prn); diff --git a/src/conio/cterm.h b/src/conio/cterm.h index 5aabe04686..7f9fb56338 100644 --- a/src/conio/cterm.h +++ b/src/conio/cterm.h @@ -56,6 +56,7 @@ typedef enum { CTERM_EMULATION_ANSI_BBS ,CTERM_EMULATION_PETASCII ,CTERM_EMULATION_ATASCII + ,CTERM_EMULATION_PRESTEL } cterm_emulation_t; typedef enum { @@ -127,6 +128,11 @@ struct cterminal { #define CTERM_EXTATTR_DECLRMM 0x0008 #define CTERM_EXTATTR_BRACKETPASTE 0x0010 #define CTERM_EXTATTR_DECBKM 0x0020 +#define CTERM_EXTATTR_PRESTEL_MOSAIC 0x0040 +#define CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT 0x0080 +#define CTERM_EXTATTR_PRESTEL_CONCEAL 0x0100 +#define CTERM_EXTATTR_PRESTEL_SEPARATED 0x0200 +#define CTERM_EXTATTR_PRESTEL_HOLD 0x0400 int save_xpos; // Saved position (for later restore) int save_ypos; int sequence; // An escape sequence is being parsed @@ -227,6 +233,7 @@ struct cterminal { /* Alternate font renderer */ void (*font_render)(char *str); int skypix; + uint8_t prestel_last_mosaic; /* conio function pointers */ #ifdef CTERM_WITHOUT_CONIO diff --git a/src/conio/utf8_codepages.c b/src/conio/utf8_codepages.c index 1bdb9e67ff..0be160741b 100644 --- a/src/conio/utf8_codepages.c +++ b/src/conio/utf8_codepages.c @@ -1465,6 +1465,122 @@ const static uint32_t petsciil_unicode_table[256] = { 0x1fb83,0x2583, 0x2713, 0x2596, 0x259d, 0x2518, 0x2598,0x1fb96 }; +const static struct ciolib_cpmap prestel_table[] = { + {0xa3, '#'}, // £ + {0x2190, '['}, // ← + {0xbd, '\\'}, // ½ + {0x2192, ']'}, // → + {0x2191, '^'}, // ↑ + {0x2317, '_'}, // Viewdata square + {'_', '`'}, + {0xbc, '{'}, // ¼ + {0xbe, '}'}, // ¾ + {0xf7, '~'}, // ÷ + + /* Space */ {0x1fb00, 129}, {0x1fb01, 130}, {0x1fb02, 131}, + {0x1fb03, 132}, {0x1fb04, 133}, {0x1fb05, 134}, {0x1fb06, 135}, + {0x1fb07, 136}, {0x1fb08, 137}, {0x1fb09, 138}, {0x1fb0a, 139}, + {0x1fb0b, 140}, {0x1fb0c, 141}, {0x1fb0d, 142}, {0x1fb0e, 143}, + {0x1fb0f, 144}, {0x1fb10, 145}, {0x1fb11, 146}, {0x1fb12, 147}, + {0x1fb13, 148}, { 0x258c, 149}, {0x1fb14, 150}, {0x1fb15, 151}, + {0x1fb16, 152}, {0x1fb17, 153}, {0x1fb18, 154}, {0x1fb19, 155}, + {0x1fb1a, 156}, {0x1fb1b, 157}, {0x1fb1c, 158}, {0x1fb1d, 159}, + {0x1fb1e, 160}, {0x1fb1f, 161}, {0x1fb20, 162}, {0x1fb21, 163}, + {0x1fb22, 164}, {0x1fb23, 165}, {0x1fb24, 166}, {0x1fb25, 167}, + {0x1fb26, 168}, {0x1fb27, 169}, { 0x2590, 170}, {0x1fb28, 171}, + {0x1fb29, 172}, {0x1fb2a, 173}, {0x1fb2b, 174}, {0x1fb2c, 175}, + {0x1fb2d, 176}, {0x1fb2e, 177}, {0x1fb2f, 178}, {0x1fb30, 179}, + {0x1fb31, 180}, {0x1fb32, 181}, {0x1fb33, 182}, {0x1fb34, 183}, + {0x1fb35, 184}, {0x1fb36, 185}, {0x1fb37, 186}, {0x1fb38, 187}, + {0x1fb39, 188}, {0x1fb3a, 189}, {0x1fb3b, 190}, { 0x2588, 191}, + + /* Space */ {0x1ce51, 193}, {0x1ce52, 194}, {0x1ce53, 195}, + {0x1ce54, 196}, {0x1ce55, 197}, {0x1ce56, 198}, {0x1ce57, 199}, + {0x1ce58, 200}, {0x1ce59, 201}, {0x1ce5a, 202}, {0x1ce5b, 203}, + {0x1ce5c, 204}, {0x1ce5d, 205}, {0x1ce5e, 206}, {0x1ce5f, 207}, + {0x1ce60, 208}, {0x1ce61, 209}, {0x1ce62, 210}, {0x1ce63, 211}, + {0x1ce64, 212}, {0x1ce65, 213}, {0x1ce66, 214}, {0x1ce67, 215}, + {0x1ce68, 216}, {0x1ce69, 217}, {0x1ce6a, 218}, {0x1ce6b, 219}, + {0x1ce6c, 220}, {0x1ce6d, 221}, {0x1ce6e, 222}, {0x1ce6f, 223}, + {0x1ce70, 224}, {0x1ce71, 225}, {0x1ce72, 226}, {0x1ce73, 227}, + {0x1ce74, 228}, {0x1ce75, 229}, {0x1ce76, 230}, {0x1ce77, 231}, + {0x1ce78, 232}, {0x1ce79, 233}, {0x1ce7a, 234}, {0x1ce7b, 235}, + {0x1ce7c, 236}, {0x1ce7d, 237}, {0x1ce7e, 238}, {0x1ce7f, 239}, + {0x1ce80, 240}, {0x1ce81, 241}, {0x1ce82, 242}, {0x1ce83, 243}, + {0x1ce84, 244}, {0x1ce85, 245}, {0x1ce86, 246}, {0x1ce87, 247}, + {0x1ce88, 248}, {0x1ce89, 249}, {0x1ce8a, 250}, {0x1ce8b, 251}, + {0x1ce8c, 252}, {0x1ce8d, 253}, {0x1ce8e, 254}, {0x1ce8f, 255} +}; + +const static uint32_t prestel_unicode_table[256] = { + 0x00000, 0x00001, 0x00002, 0x00003, + 0x00004, 0x00005, 0x00006, 0x00007, + 0x00008, 0x00009, 0x0000a, 0x0000b, + 0x0000c, 0x0000d, 0x0000e, 0x0000f, + 0x00010, 0x00011, 0x00012, 0x00013, + 0x00014, 0x00015, 0x00016, 0x00017, + 0x00018, 0x00019, 0x0001a, 0x0001b, + 0x0001c, 0x0001d, 0x0001e, 0x0001f, + 0x00020, 0x00021, 0x00022, 0x000a3, + 0x00024, 0x00025, 0x00026, 0x00027, + 0x00028, 0x00029, 0x0002a, 0x0002b, + 0x0002c, 0x0002d, 0x0002e, 0x0002f, + 0x00030, 0x00031, 0x00032, 0x00033, + 0x00034, 0x00035, 0x00036, 0x00037, + 0x00038, 0x00039, 0x0003a, 0x0003b, + 0x0003c, 0x0003d, 0x0003e, 0x0003f, + 0x00040, 0x00041, 0x00042, 0x00043, + 0x00044, 0x00045, 0x00046, 0x00047, + 0x00048, 0x00049, 0x0004a, 0x0004b, + 0x0004c, 0x0004d, 0x0004e, 0x0004f, + 0x00050, 0x00051, 0x00052, 0x00053, + 0x00054, 0x00055, 0x00056, 0x00057, + 0x00058, 0x00059, 0x0005a, 0x02190, + 0x000bd, 0x02192, 0x02191, 0x02317, + 0x0005f, 0x00061, 0x00062, 0x00063, + 0x00064, 0x00065, 0x00066, 0x00067, + 0x00068, 0x00069, 0x0006a, 0x0006b, + 0x0006c, 0x0006d, 0x0006e, 0x0006f, + 0x00070, 0x00071, 0x00072, 0x00073, + 0x00074, 0x00075, 0x00076, 0x00077, + 0x00078, 0x00079, 0x0007a, 0x000bc, + 0x0007c, 0x000be, 0x000f7, 0x0007f, + + 0x00020, 0x1fb00, 0x1fb01, 0x1fb02, + 0x1fb03, 0x1fb04, 0x1fb05, 0x1fb06, + 0x1fb07, 0x1fb08, 0x1fb09, 0x1fb0a, + 0x1fb0b, 0x1fb0c, 0x1fb0d, 0x1fb0e, + 0x1fb0f, 0x1fb10, 0x1fb11, 0x1fb12, + 0x1fb13, 0x258c, 0x1fb14, 0x1fb15, + 0x1fb16, 0x1fb17, 0x1fb18, 0x1fb19, + 0x1fb1a, 0x1fb1b, 0x1fb1c, 0x1fb1d, + 0x1fb1e, 0x1fb1f, 0x1fb20, 0x1fb21, + 0x1fb22, 0x1fb23, 0x1fb24, 0x1fb25, + 0x1fb26, 0x1fb27, 0x2590, 0x1fb28, + 0x1fb29, 0x1fb2a, 0x1fb2b, 0x1fb2c, + 0x1fb2d, 0x1fb2e, 0x1fb2f, 0x1fb30, + 0x1fb31, 0x1fb32, 0x1fb33, 0x1fb34, + 0x1fb35, 0x1fb36, 0x1fb37, 0x1fb38, + 0x1fb39, 0x1fb3a, 0x1fb3b, 0x2588, + + 0x00020, 0x1ce51, 0x1ce52, 0x1ce53, + 0x1ce54, 0x1ce55, 0x1ce56, 0x1ce57, + 0x1ce58, 0x1ce59, 0x1ce5a, 0x1ce5b, + 0x1ce5c, 0x1ce5d, 0x1ce5e, 0x1ce5f, + 0x1ce60, 0x1ce61, 0x1ce62, 0x1ce63, + 0x1ce64, 0x1ce65, 0x1ce66, 0x1ce67, + 0x1ce68, 0x1ce69, 0x1ce6a, 0x1ce6b, + 0x1ce6c, 0x1ce6d, 0x1ce6e, 0x1ce6f, + 0x1ce70, 0x1ce71, 0x1ce72, 0x1ce73, + 0x1ce74, 0x1ce75, 0x1ce76, 0x1ce77, + 0x1ce78, 0x1ce79, 0x1ce7a, 0x1ce7b, + 0x1ce7c, 0x1ce7d, 0x1ce7e, 0x1ce7f, + 0x1ce80, 0x1ce81, 0x1ce82, 0x1ce83, + 0x1ce84, 0x1ce85, 0x1ce86, 0x1ce87, + 0x1ce88, 0x1ce89, 0x1ce8a, 0x1ce8b, + 0x1ce8c, 0x1ce8d, 0x1ce8e, 0x1ce8f +}; + static int cmptab(const void *key, const void *entry) { @@ -1889,6 +2005,10 @@ const struct codepage_def ciolib_cp[CIOLIB_CP_COUNT] = { {"PETSCIIL", CIOLIB_PETSCIIL, ftstr_to_utf8, utf8_to_cpstr, ft_from_unicode_cpoint, ft_cpoint_from_cptable, cpoint_from_cptable_ext, petsciil_table, sizeof(petsciil_table) / sizeof(petsciil_table[0]), petsciil_unicode_table, empty_ext_table}, + + {"PRESTEL", CIOLIB_PRESTEL, ftstr_to_utf8, utf8_to_cpstr, ft_from_unicode_cpoint, ft_cpoint_from_cptable, cpoint_from_cptable_ext, + prestel_table, sizeof(prestel_table) / sizeof(prestel_table[0]), + prestel_unicode_table, empty_ext_table}, }; uint8_t *cp_to_utf8(enum ciolib_codepage cp, const char *cpstr, size_t buflen, size_t *outlen) diff --git a/src/conio/utf8_codepages.h b/src/conio/utf8_codepages.h index 96235f4fe9..65846a3420 100644 --- a/src/conio/utf8_codepages.h +++ b/src/conio/utf8_codepages.h @@ -25,6 +25,7 @@ enum ciolib_codepage { CIOLIB_ATASCII, CIOLIB_PETSCIIU, CIOLIB_PETSCIIL, + CIOLIB_PRESTEL, CIOLIB_CP_COUNT }; diff --git a/src/conio/vidmodes.c b/src/conio/vidmodes.c index ffb74d430c..f25c03e220 100644 --- a/src/conio/vidmodes.c +++ b/src/conio/vidmodes.c @@ -124,11 +124,13 @@ struct video_params vparams[] = { {VGA80X25, COLOUR_PALETTE, 80, 25, 14, 15, 16, 9, 7, CIOLIB_VIDEO_EXPAND | CIOLIB_VIDEO_LINE_GRAPHICS_EXPAND, 4, 3, 720, 400}, /* DigitalMon */ {LCD80X25, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 8, 5, 640, 400}, + /* Prestel */ + {PRESTEL_40X24, PRESTEL_PALETTE, 40, 24, 14, 15, 16, 8, 7, 0, 4, 3, 320, 384}, /* Custom mode */ - {CIOLIB_MODE_CUSTOM, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 0, 0, -1, -1}, + {CIOLIB_MODE_CUSTOM, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 0, 0, -1, -1}, }; -uint32_t palettes[5][16] = { +uint32_t palettes[6][16] = { /* Mono */ { 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 @@ -149,6 +151,10 @@ uint32_t palettes[5][16] = { { 0x110, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111, 0x111 }, + /* Prestel */ + { 0, 21, 46, 51, 196, 201, 226, 15, + 0, 21, 46, 51, 196, 201, 226, 15 + }, }; struct dac_colors dac_default[TOTAL_DAC_SIZE] = { @@ -172,63 +178,63 @@ struct dac_colors dac_default[TOTAL_DAC_SIZE] = { {255, 255, 255}, // White /* XTerm 256 colour palette */ - {0, 0, 0}, {0, 0, 95}, {0, 0, 135}, {0, 0, 175}, + {0, 0, 0}, {0, 0, 95}, {0, 0, 135}, {0, 0, 175}, // 16 {0, 0, 215}, {0, 0, 255}, {0, 95, 0}, {0, 95, 95}, {0, 95, 135}, {0, 95, 175}, {0, 95, 215}, {0, 95, 255}, {0, 135, 0}, {0, 135, 95}, {0, 135, 135}, {0, 135, 175}, - {0, 135, 215}, {0, 135, 255}, {0, 175, 0}, {0, 175, 95}, + {0, 135, 215}, {0, 135, 255}, {0, 175, 0}, {0, 175, 95}, // 32 {0, 175, 135}, {0, 175, 175}, {0, 175, 215}, {0, 175, 255}, {0, 215, 0}, {0, 215, 95}, {0, 215, 135}, {0, 215, 175}, {0, 215, 215}, {0, 215, 255}, {0, 255, 0}, {0, 255, 95}, - {0, 255, 135}, {0, 255, 175}, {0, 255, 215}, {0, 255, 255}, + {0, 255, 135}, {0, 255, 175}, {0, 255, 215}, {0, 255, 255}, // 48 {95, 0, 0}, {95, 0, 95}, {95, 0, 135}, {95, 0, 175}, {95, 0, 215}, {95, 0, 255}, {95, 95, 0}, {95, 95, 95}, {95, 95, 135}, {95, 95, 175}, {95, 95, 215}, {95, 95, 255}, - {95, 135, 0}, {95, 135, 95}, {95, 135, 135}, {95, 135, 175}, + {95, 135, 0}, {95, 135, 95}, {95, 135, 135}, {95, 135, 175}, // 64 {95, 135, 215}, {95, 135, 255}, {95, 175, 0}, {95, 175, 95}, {95, 175, 135}, {95, 175, 175}, {95, 175, 215}, {95, 175, 255}, {95, 215, 0}, {95, 215, 95}, {95, 215, 135}, {95, 215, 175}, - {95, 215, 215}, {95, 215, 255}, {95, 255, 0}, {95, 255, 95}, + {95, 215, 215}, {95, 215, 255}, {95, 255, 0}, {95, 255, 95}, // 80 {95, 255, 135}, {95, 255, 175}, {95, 255, 215}, {95, 255, 255}, {135, 0, 0}, {135, 0, 95}, {135, 0, 135}, {135, 0, 175}, {135, 0, 215}, {135, 0, 255}, {135, 95, 0}, {135, 95, 95}, - {135, 95, 135}, {135, 95, 175}, {135, 95, 215}, {135, 95, 255}, + {135, 95, 135}, {135, 95, 175}, {135, 95, 215}, {135, 95, 255}, // 96 {135, 135, 0}, {135, 135, 95}, {135, 135, 135}, {135, 135, 175}, {135, 135, 215}, {135, 135, 255}, {135, 175, 0}, {135, 175, 95}, {135, 175, 135}, {135, 175, 175}, {135, 175, 215}, {135, 175, 255}, - {135, 215, 0}, {135, 215, 95}, {135, 215, 135}, {135, 215, 175}, + {135, 215, 0}, {135, 215, 95}, {135, 215, 135}, {135, 215, 175}, // 112 {135, 215, 215}, {135, 215, 255}, {135, 255, 0}, {135, 255, 95}, {135, 255, 135}, {135, 255, 175}, {135, 255, 215}, {135, 255, 255}, {175, 0, 0}, {175, 0, 95}, {175, 0, 135}, {175, 0, 175}, - {175, 0, 215}, {175, 0, 255}, {175, 95, 0}, {175, 95, 95}, + {175, 0, 215}, {175, 0, 255}, {175, 95, 0}, {175, 95, 95}, // 128 {175, 95, 135}, {175, 95, 175}, {175, 95, 215}, {175, 95, 255}, {175, 135, 0}, {175, 135, 95}, {175, 135, 135}, {175, 135, 175}, {175, 135, 215}, {175, 135, 255}, {175, 175, 0}, {175, 175, 95}, - {175, 175, 135}, {175, 175, 175}, {175, 175, 215}, {175, 175, 255}, + {175, 175, 135}, {175, 175, 175}, {175, 175, 215}, {175, 175, 255}, // 144 {175, 215, 0}, {175, 215, 95}, {175, 215, 135}, {175, 215, 175}, {175, 215, 215}, {175, 215, 255}, {175, 255, 0}, {175, 255, 95}, {175, 255, 135}, {175, 255, 175}, {175, 255, 215}, {175, 255, 255}, - {215, 0, 0}, {215, 0, 95}, {215, 0, 135}, {215, 0, 175}, + {215, 0, 0}, {215, 0, 95}, {215, 0, 135}, {215, 0, 175}, // 160 {215, 0, 215}, {215, 0, 255}, {215, 95, 0}, {215, 95, 95}, {215, 95, 135}, {215, 95, 175}, {215, 95, 215}, {215, 95, 255}, {215, 135, 0}, {215, 135, 95}, {215, 135, 135}, {215, 135, 175}, - {215, 135, 215}, {215, 135, 255}, {215, 175, 0}, {215, 175, 95}, + {215, 135, 215}, {215, 135, 255}, {215, 175, 0}, {215, 175, 95}, // 176 {215, 175, 135}, {215, 175, 175}, {215, 175, 215}, {215, 175, 255}, {215, 215, 0}, {215, 215, 95}, {215, 215, 135}, {215, 215, 175}, {215, 215, 215}, {215, 215, 255}, {215, 255, 0}, {215, 255, 95}, - {215, 255, 135}, {215, 255, 175}, {215, 255, 215}, {215, 255, 255}, + {215, 255, 135}, {215, 255, 175}, {215, 255, 215}, {215, 255, 255}, // 192 {255, 0, 0}, {255, 0, 95}, {255, 0, 135}, {255, 0, 175}, {255, 0, 215}, {255, 0, 255}, {255, 95, 0}, {255, 95, 95}, {255, 95, 135}, {255, 95, 175}, {255, 95, 215}, {255, 95, 255}, - {255, 135, 0}, {255, 135, 95}, {255, 135, 135}, {255, 135, 175}, + {255, 135, 0}, {255, 135, 95}, {255, 135, 135}, {255, 135, 175}, // 208 {255, 135, 215}, {255, 135, 255}, {255, 175, 0}, {255, 175, 95}, {255, 175, 135}, {255, 175, 175}, {255, 175, 215}, {255, 175, 255}, {255, 215, 0}, {255, 215, 95}, {255, 215, 135}, {255, 215, 175}, - {255, 215, 215}, {255, 215, 255}, {255, 255, 0}, {255, 255, 95}, + {255, 215, 215}, {255, 215, 255}, {255, 255, 0}, {255, 255, 95}, // 224 {255, 255, 135}, {255, 255, 175}, {255, 255, 215}, {255, 255, 255}, {8, 8, 8}, {18, 18, 18}, {28, 28, 28}, {38, 38, 38}, {48, 48, 48}, {58, 58, 58}, {68, 68, 68}, {78, 78, 78}, - {88, 88, 88}, {98, 98, 98}, {108, 108, 108}, {118, 118, 118}, + {88, 88, 88}, {98, 98, 98}, {108, 108, 108}, {118, 118, 118}, // 240 {128, 128, 128}, {138, 138, 138}, {148, 148, 148}, {158, 158, 158}, {168, 168, 168}, {178, 178, 178}, {188, 188, 188}, {198, 198, 198}, {208, 208, 208}, {218, 218, 218}, {228, 228, 228}, {238, 238, 238}, @@ -259,7 +265,7 @@ struct dac_colors dac_default[TOTAL_DAC_SIZE] = { * Taken from https://www.pepto.de/projects/colorvic/ * a much more convincing source. */ - {0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00}, // 256 {0xFF, 0xFF, 0xFF}, {0x81, 0x33, 0x38}, {0x75, 0xCE, 0xC8}, diff --git a/src/conio/vidmodes.h b/src/conio/vidmodes.h index 411cd22be8..634fcde70a 100644 --- a/src/conio/vidmodes.h +++ b/src/conio/vidmodes.h @@ -118,11 +118,12 @@ enum { ,COLOUR_PALETTE ,C64_PALETTE ,ATARI_PALETTE + ,PRESTEL_PALETTE }; -extern struct video_params vparams[56]; +extern struct video_params vparams[57]; #define NUMMODES (sizeof(vparams) / sizeof(struct video_params)) -extern uint32_t palettes[5][16]; +extern uint32_t palettes[6][16]; extern struct dac_colors dac_default[TOTAL_DAC_SIZE]; extern char vga_font_bitmap[4096]; extern char vga_font_bitmap14[3584]; diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index 6ea9f124b7..04b925313c 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -233,12 +233,12 @@ int sortorder[sizeof(sort_order) / sizeof(struct sort_ static char *screen_modes[] = { "Current", "80x25", "LCD 80x25", "80x28", "80x30", "80x43", "80x50", "80x60", "132x37 (16:9)", "132x52 (5:4)", "132x25", "132x28", "132x30", "132x34", "132x43", "132x50", "132x60", "C64", "C128 (40col)", "C128 (80col)", - "Atari", "Atari XEP80", "Custom", "EGA 80x25", "VGA 80x25", NULL + "Atari", "Atari XEP80", "Custom", "EGA 80x25", "VGA 80x25", "Prestel", NULL }; char *screen_modes_enum[] = { "Current", "80x25", "LCD80x25", "80x28", "80x30", "80x43", "80x50", "80x60", "132x37", "132x52", "132x25", "132x28", "132x30", "132x34", "132x43", "132x50", "132x60", "C64", "C128-40col", "C128-80col", "Atari", - "Atari-XEP80", "Custom", "EGA80x25", "VGA80x25", NULL + "Atari-XEP80", "Custom", "EGA80x25", "VGA80x25", "Prestel", NULL }; char *log_levels[] = { @@ -1579,9 +1579,20 @@ edit_list(struct bbslist **list, struct bbslist *item, char *listpath, int isdef item->nostatus, &ini_style); } + else if (item->screen_mode == SCREEN_MODE_PRESTEL) { + SAFECOPY(item->font, font_names[43]); + iniSetString(&inifile, itemname, "Font", item->font, + &ini_style); + item->nostatus = 1; + iniSetBool(&inifile, + itemname, + "NoStatus", + item->nostatus, + &ini_style); + } else if ((i == SCREEN_MODE_C64) || (i == SCREEN_MODE_C128_40) || (i == SCREEN_MODE_C128_80) || (i == SCREEN_MODE_ATARI) - || (i == SCREEN_MODE_ATARI_XEP80)) { + || (i == SCREEN_MODE_ATARI_XEP80) || (i == SCREEN_MODE_PRESTEL)) { SAFECOPY(item->font, font_names[0]); iniSetString(&inifile, itemname, "Font", item->font, &ini_style); @@ -3495,6 +3506,8 @@ get_emulation(struct bbslist *bbs) case SCREEN_MODE_ATARI: case SCREEN_MODE_ATARI_XEP80: return CTERM_EMULATION_ATASCII; + case SCREEN_MODE_PRESTEL: + return CTERM_EMULATION_PRESTEL; default: return CTERM_EMULATION_ANSI_BBS; } @@ -3510,6 +3523,8 @@ get_emulation_str(cterm_emulation_t emu) return "PETSCII"; case CTERM_EMULATION_ATASCII: return "ATASCII"; + case CTERM_EMULATION_PRESTEL: + return "Prestel"; } return "none"; } diff --git a/src/syncterm/bbslist.h b/src/syncterm/bbslist.h index e1c9406e44..29c1dfe2b6 100644 --- a/src/syncterm/bbslist.h +++ b/src/syncterm/bbslist.h @@ -88,6 +88,8 @@ enum { , SCREEN_MODE_VGA_80X25 , + SCREEN_MODE_PRESTEL + , SCREEN_MODE_TERMINATOR }; diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c index 3f7397b650..3101cfc9f3 100644 --- a/src/syncterm/syncterm.c +++ b/src/syncterm/syncterm.c @@ -2265,6 +2265,8 @@ screen_to_ciolib(int screen) return EGA80X25; case SCREEN_MODE_VGA_80X25: return VGA80X25; + case SCREEN_MODE_PRESTEL: + return PRESTEL_40X24; } gettextinfo(&ti); return ti.currmode; @@ -2320,6 +2322,8 @@ ciolib_to_screen(int ciolib) return SCREEN_MODE_CUSTOM; case EGA80X25: return SCREEN_MODE_EGA_80X25; + case PRESTEL_40X24: + return SCREEN_MODE_PRESTEL; } return SCREEN_MODE_CURRENT; } diff --git a/src/syncterm/term.c b/src/syncterm/term.c index d5ab686fff..39a4c99227 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -4413,6 +4413,51 @@ doterm(struct bbslist *bbs) break; } } + else if (key && (cterm->emulation == CTERM_EMULATION_PRESTEL)) { + switch (key) { + case '#': + ch[0] = '_'; + conn_send(ch, 1, 0); + break; + // TODO: Can send control chars instead... + case 8: + case CIO_KEY_DC: + case CIO_KEY_LEFT: + ch[0] = 8; + conn_send(ch, 1, 0); + break; + case CIO_KEY_RIGHT: + ch[0] = 9; + conn_send(ch, 1, 0); + break; + case CIO_KEY_UP: + ch[0] = 11; + conn_send(ch, 1, 0); + break; + case CIO_KEY_DOWN: + ch[0] = 10; + conn_send(ch, 1, 0); + break; + case CIO_KEY_HOME: + ch[0] = 0x1f; + conn_send(ch, 1, 0); + break; + case '_': + ch[0] = '`'; + conn_send(ch, 1, 0); + break; + // TODO: Map £ ('#'), ½ (\), ¼ ({), ¾ (}), ÷ (~) + // TODO: Add Reveal key + // TODO: Add clear screen key + // TODO: Make return # or some shit... + default: + if (key == 13 || (key < 129 && key > 31)) { + ch[0] = key; + conn_send(ch, 1, 0); + } + break; + } + } else if (key) { switch (key) { case CIO_KEY_LEFT: -- GitLab