diff options
Diffstat (limited to 'engines/glk/adrift/os_glk.cpp')
-rw-r--r-- | engines/glk/adrift/os_glk.cpp | 4306 |
1 files changed, 2049 insertions, 2257 deletions
diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp index 33253802a2..37ac07f941 100644 --- a/engines/glk/adrift/os_glk.cpp +++ b/engines/glk/adrift/os_glk.cpp @@ -89,9 +89,9 @@ static const sc_int GSC_CONF_SUBTLE_HINT = INT_MAX, GSC_CONF_CONTINUE_HINTS = INT_MAX - 2; /* Forward declaration of event wait functions, and a short delay. */ -static void gsc_event_wait_2 (glui32 wait_type_1, - glui32 wait_type_2, event_t *event); -static void gsc_event_wait (glui32 wait_type, event_t *event); +static void gsc_event_wait_2(glui32 wait_type_1, + glui32 wait_type_2, event_t *event); +static void gsc_event_wait(glui32 wait_type, event_t *event); static void gsc_short_delay(); @@ -106,29 +106,28 @@ static void gsc_short_delay(); * abort() or otherwise handle the error. */ static void -gsc_fatal (const char *string) -{ - /* - * If the failure happens too early for us to have a window, print - * the message to stderr. - */ - if (!gsc_main_window) { - error("\n\nINTERNAL ERROR: %s\n", string); - } +gsc_fatal(const char *string) { + /* + * If the failure happens too early for us to have a window, print + * the message to stderr. + */ + if (!gsc_main_window) { + error("\n\nINTERNAL ERROR: %s\n", string); + } - /* Cancel all possible pending window input events. */ - g_vm->glk_cancel_line_event (gsc_main_window, nullptr); - g_vm->glk_cancel_char_event (gsc_main_window); + /* Cancel all possible pending window input events. */ + g_vm->glk_cancel_line_event(gsc_main_window, nullptr); + g_vm->glk_cancel_char_event(gsc_main_window); - /* Print a message indicating the error, and exit. */ - g_vm->glk_set_window (gsc_main_window); - g_vm->glk_set_style (style_Normal); - g_vm->glk_put_string ("\n\nINTERNAL ERROR: "); - g_vm->glk_put_string ((char *) string); + /* Print a message indicating the error, and exit. */ + g_vm->glk_set_window(gsc_main_window); + g_vm->glk_set_style(style_Normal); + g_vm->glk_put_string("\n\nINTERNAL ERROR: "); + g_vm->glk_put_string((char *) string); - g_vm->glk_put_string ("\n\nPlease record the details of this error, try to" - " note down everything you did to cause it, and email" - " this information to simon_baldwin@yahoo.com.\n\n"); + g_vm->glk_put_string("\n\nPlease record the details of this error, try to" + " note down everything you did to cause it, and email" + " this information to simon_baldwin@yahoo.com.\n\n"); } @@ -138,18 +137,16 @@ gsc_fatal (const char *string) * Non-failing malloc; call gsc_fatal and exit if memory allocation fails. */ static void * -gsc_malloc (size_t size) -{ - void *pointer; +gsc_malloc(size_t size) { + void *pointer; - pointer = malloc (size > 0 ? size : 1); - if (!pointer) - { - gsc_fatal ("GLK: Out of system memory"); - g_vm->glk_exit (); - } + pointer = malloc(size > 0 ? size : 1); + if (!pointer) { + gsc_fatal("GLK: Out of system memory"); + g_vm->glk_exit(); + } - return pointer; + return pointer; } @@ -170,8 +167,8 @@ static const glui32 GSC_ISO_8859_EQUIVALENCE = 256; */ enum { GSC_TABLE_SIZE = 256 }; typedef struct { - const glui32 unicode[GSC_TABLE_SIZE]; - const sc_char *const ascii[GSC_TABLE_SIZE]; + const glui32 unicode[GSC_TABLE_SIZE]; + const sc_char *const ascii[GSC_TABLE_SIZE]; } gsc_codepages_t; /* @@ -179,9 +176,9 @@ typedef struct { * an alternate. The latter is intended for monospaced output. */ typedef struct { - const sc_char *const name; - const gsc_codepages_t main; - const gsc_codepages_t alternate; + const sc_char *const name; + const gsc_codepages_t main; + const gsc_codepages_t alternate; } gsc_locale_t; @@ -195,117 +192,127 @@ typedef struct { * character that might be recognizable as what it's trying to emulate. */ static const gsc_locale_t GSC_LATIN1_LOCALE = { - "Latin1", - /* cp1252 to unicode. */ -{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, - 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, - 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, 0x00a0, 0x00a1, - 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, - 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, - 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, - 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, - 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, - 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, - 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, - 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, - 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, - 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, - 0x00fc, 0x00fd, 0x00fe, 0x00ff }, - /* cp1252 to ascii. */ - { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", - "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", - "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", - "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", - "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", nullptr, "E", nullptr, ",", - "f", ",,", "...", "+", "#", "^", "%", "S", "<", "OE", nullptr, - "Z", nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", "~", - "[TM]","s", ">", "oe", nullptr, "z", "Y", " ", "!", "c", "GBP", - "*", "Y", "|", "S", "\"", "(C)", "a", "<<", "-", "-", "(R)", - "-", "o", "+/-", "2", "3", "'", "u", "P", "*", ",", "1", - "o", ">>", "1/4", "1/2", "3/4", "?", "A", "A", "A", "A", "A", - "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I", - "D", "N", "O", "O", "O", "O", "O", "x", "O", "U", "U", - "U", "U", "Y", "p", "ss", "a", "a", "a", "a", "a", "a", - "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d", - "n", "o", "o", "o", "o", "o", "/", "o", "u", "u", "u", - "u", "y", "P", "y" } }, - /* cp850 to unicode. */ -{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, - 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, - 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, - 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed, - 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac, - 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, - 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, - 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, - 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, - 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, - 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3, - 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da, - 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1, 0x2017, - 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9, - 0x00b3, 0x00b2, 0x25a0, 0x00a0 }, - /* cp850 to ascii. */ - { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", - "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", - "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", - "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", - "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", nullptr, "C", "u", "e", - "a", "a", "a", "a", "c", "e", "e", "e", "i", "i", "i", - "A", "A", "E", "ae", "AE", "o", "o", "o", "u", "u", "y", - "O", "U", "o", "GBP", "O", "x", "f", "a", "i", "o", "u", - "n", "N", "a", "o", "?", "(R)", "-", "1/2", "1/4", "i", "<<", - ">>", "#", "#", "#", "|", "+", "A", "A", "A", "(C)", "+", - "|", "+", "+", "c", "Y", "+", "+", "+", "+", "+", "-", - "+", "a", "A", "+", "+", "+", "+", "+", "=", "+", "*", - "d", "D", "E", "E", "E", "i", "I", "I", "I", "+", "+", - ".", ".", "|", "I", ".", "O", "ss", "O", "O", "o", "O", - "u", "p", "P", "U", "U", "U", "y", "Y", "-", "'", "-", - "+/-", "=", "3/4", "P", "S", "/", ",", "deg", "\"", "*", "1", - "3", "2", ".", " " } } + "Latin1", + /* cp1252 to unicode. */ + { { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, + 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, + 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, 0x00a0, 0x00a1, + 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, + 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, + 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, + 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, + 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, + 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, + 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, + 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff + }, + /* cp1252 to ascii. */ + { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", + "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", + "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", + "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", nullptr, "E", nullptr, ",", + "f", ",,", "...", "+", "#", "^", "%", "S", "<", "OE", nullptr, + "Z", nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", "~", + "[TM]", "s", ">", "oe", nullptr, "z", "Y", " ", "!", "c", "GBP", + "*", "Y", "|", "S", "\"", "(C)", "a", "<<", "-", "-", "(R)", + "-", "o", "+/-", "2", "3", "'", "u", "P", "*", ",", "1", + "o", ">>", "1/4", "1/2", "3/4", "?", "A", "A", "A", "A", "A", + "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I", + "D", "N", "O", "O", "O", "O", "O", "x", "O", "U", "U", + "U", "U", "Y", "p", "ss", "a", "a", "a", "a", "a", "a", + "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d", + "n", "o", "o", "o", "o", "o", "/", "o", "u", "u", "u", + "u", "y", "P", "y" + } + }, + /* cp850 to unicode. */ + { { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, + 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, + 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed, + 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac, + 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, + 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, + 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3, + 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da, + 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1, 0x2017, + 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9, + 0x00b3, 0x00b2, 0x25a0, 0x00a0 + }, + /* cp850 to ascii. */ + { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", + "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", + "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", + "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", nullptr, "C", "u", "e", + "a", "a", "a", "a", "c", "e", "e", "e", "i", "i", "i", + "A", "A", "E", "ae", "AE", "o", "o", "o", "u", "u", "y", + "O", "U", "o", "GBP", "O", "x", "f", "a", "i", "o", "u", + "n", "N", "a", "o", "?", "(R)", "-", "1/2", "1/4", "i", "<<", + ">>", "#", "#", "#", "|", "+", "A", "A", "A", "(C)", "+", + "|", "+", "+", "c", "Y", "+", "+", "+", "+", "+", "-", + "+", "a", "A", "+", "+", "+", "+", "+", "=", "+", "*", + "d", "D", "E", "E", "E", "i", "I", "I", "I", "+", "+", + ".", ".", "|", "I", ".", "O", "ss", "O", "O", "o", "O", + "u", "p", "P", "U", "U", "U", "y", "Y", "-", "'", "-", + "+/-", "=", "3/4", "P", "S", "/", ",", "deg", "\"", "*", "1", + "3", "2", ".", " " + } + } }; @@ -321,117 +328,127 @@ static const gsc_locale_t GSC_LATIN1_LOCALE = { * the general appearance and shape of the character being emulated is used. */ static const gsc_locale_t GSC_CYRILLIC_LOCALE = { - "Cyrillic", - /* cp1251 to unicode. */ -{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, - 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, - 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, - 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, 0x00a0, 0x040e, - 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, - 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, 0x00b0, 0x00b1, 0x0406, 0x0456, - 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, - 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, - 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, - 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, - 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, - 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, - 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, - 0x044c, 0x044d, 0x044e, 0x044f }, - /* cp1251 to gost 16876-71 ascii. */ - { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", - "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", - "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", - "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", - "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", nullptr, nullptr, nullptr, ",", - nullptr, ",,", "...", "+", "#", "E", "%", nullptr, "<", nullptr, nullptr, - nullptr, nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", nullptr, - "[TM]",nullptr, ">", nullptr, nullptr, nullptr, nullptr, " ", nullptr, nullptr, nullptr, - "*", "G", "|", "S", "Jo", "(C)", "Je", "<<", "-", "-", "(R)", - "Ji", "o", "+/-", "I", "i", "g", "u", "P", "*", "jo", nullptr, - "je", ">>", "j", "S", "s", "ji", "A", "B", "V", "G", "D", - "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", "O", "P", - "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", "Shh", "\"", - "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", "d", "e", - "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r", - "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "\"", "y", - "'", "eh", "ju", "ja" } }, - /* cp866 to unicode. */ -{ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, - 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, - 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431, - 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, - 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x2591, 0x2592, 0x2593, 0x2502, - 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, - 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, - 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, - 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, - 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x0440, - 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, - 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0401, 0x0451, 0x0404, - 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, 0x00b0, 0x2022, 0x00b7, 0x221a, - 0x2116, 0x00a4, 0x25a0, 0x00a0 }, - /* cp866 to gost 16876-71 ascii. */ - { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", - "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", - "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", - "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", - "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", nullptr, "A", "B", "V", - "G", "D", "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", - "O", "P", "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", - "Shh", "\"", "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", - "d", "e", "zh", "z", "i", "jj", "k", "l", "m", "n", "o", - "p", "#", "#", "#", "|", "+", "+", "+", "+", "+", "+", - "|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "-", - "+", "+", "+", "+", "+", "+", "+", "+", "|", "+", "+", - "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", - "+", ".", ".", ".", ".", "r", "s", "t", "u", "f", "kh", - "c", "ch", "sh", "shh", "\"", "y", "'", "eh", "ju", "ja", "Jo", - "jo", "Je", "je", "Ji", "ji", nullptr, nullptr, "deg", "*", "*", nullptr, - nullptr, "*", ".", " " } } + "Cyrillic", + /* cp1251 to unicode. */ + { { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, + 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, + 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, 0x00a0, 0x040e, + 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, + 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, 0x00b0, 0x00b1, 0x0406, 0x0456, + 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, + 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, + 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, + 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, + 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, + 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, + 0x044c, 0x044d, 0x044e, 0x044f + }, + /* cp1251 to gost 16876-71 ascii. */ + { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", + "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", + "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", + "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", nullptr, nullptr, nullptr, ",", + nullptr, ",,", "...", "+", "#", "E", "%", nullptr, "<", nullptr, nullptr, + nullptr, nullptr, nullptr, "'", "'", "\"", "\"", "*", "-", "-", nullptr, + "[TM]", nullptr, ">", nullptr, nullptr, nullptr, nullptr, " ", nullptr, nullptr, nullptr, + "*", "G", "|", "S", "Jo", "(C)", "Je", "<<", "-", "-", "(R)", + "Ji", "o", "+/-", "I", "i", "g", "u", "P", "*", "jo", nullptr, + "je", ">>", "j", "S", "s", "ji", "A", "B", "V", "G", "D", + "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", "O", "P", + "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", "Shh", "\"", + "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", "d", "e", + "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r", + "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "\"", "y", + "'", "eh", "ju", "ja" + } + }, + /* cp866 to unicode. */ + { { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, + 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, + 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, + 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0401, 0x0451, 0x0404, + 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, 0x00b0, 0x2022, 0x00b7, 0x221a, + 0x2116, 0x00a4, 0x25a0, 0x00a0 + }, + /* cp866 to gost 16876-71 ascii. */ + { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ", + "\n", nullptr, nullptr, "\n", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", + "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", + "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", nullptr, "A", "B", "V", + "G", "D", "E", "Zh", "Z", "I", "Jj", "K", "L", "M", "N", + "O", "P", "R", "S", "T", "U", "F", "Kh", "C", "Ch", "Sh", + "Shh", "\"", "Y", "'", "Eh", "Ju", "Ja", "a", "b", "v", "g", + "d", "e", "zh", "z", "i", "jj", "k", "l", "m", "n", "o", + "p", "#", "#", "#", "|", "+", "+", "+", "+", "+", "+", + "|", "+", "+", "+", "+", "+", "+", "+", "+", "+", "-", + "+", "+", "+", "+", "+", "+", "+", "+", "|", "+", "+", + "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+", + "+", ".", ".", ".", ".", "r", "s", "t", "u", "f", "kh", + "c", "ch", "sh", "shh", "\"", "y", "'", "eh", "ju", "ja", "Jo", + "jo", "Je", "je", "Ji", "ji", nullptr, nullptr, "deg", "*", "*", nullptr, + nullptr, "*", ".", " " + } + } }; @@ -447,24 +464,22 @@ static const sc_bool gsc_has_unicode = FALSE; /* Gestalt selector and stubs for non-unicode capable libraries. */ static const glui32 gestalt_Unicode = 15; -static void glk_put_char_uni (glui32 ch) -{ - glui32 unused; - unused = ch; - gsc_fatal ("GLK: Stub unicode function called"); +static void glk_put_char_uni(glui32 ch) { + glui32 unused; + unused = ch; + gsc_fatal("GLK: Stub unicode function called"); } -static void glk_request_line_event_uni (winid_t win, - glui32 *buf, glui32 maxlen, glui32 initlen) -{ - winid_t unused1; - glui32 *unused2; - glui32 unused3, unused4; - unused1 = win; - unused2 = buf; - unused3 = maxlen; - unused4 = initlen; - gsc_fatal ("GLK: Stub unicode function called"); +static void glk_request_line_event_uni(winid_t win, + glui32 *buf, glui32 maxlen, glui32 initlen) { + winid_t unused1; + glui32 *unused2; + glui32 unused3, unused4; + unused1 = win; + unused2 = buf; + unused3 = maxlen; + unused4 = initlen; + gsc_fatal("GLK: Stub unicode function called"); } #endif @@ -480,9 +495,9 @@ static const glui32 GSC_MIN_PRINTABLE = ' ', /* List of pointers to supported and available locales, nullptr terminated. */ static const gsc_locale_t *const GSC_AVAILABLE_LOCALES[] = { - &GSC_LATIN1_LOCALE, - &GSC_CYRILLIC_LOCALE, - nullptr + &GSC_LATIN1_LOCALE, + &GSC_CYRILLIC_LOCALE, + nullptr }; /* @@ -499,30 +514,27 @@ static const gsc_locale_t *const gsc_fallback_locale = &GSC_LATIN1_LOCALE; * Set a locale explicitly from the name passed in. */ static void -gsc_set_locale (const sc_char *name) -{ - const gsc_locale_t *matched = nullptr; - const gsc_locale_t *const *iterator; - assert (name); +gsc_set_locale(const sc_char *name) { + const gsc_locale_t *matched = nullptr; + const gsc_locale_t *const *iterator; + assert(name); - /* - * Search locales for a matching name, abbreviated if necessary. Stop on - * the first match found. - */ - for (iterator = GSC_AVAILABLE_LOCALES; *iterator; iterator++) - { - const gsc_locale_t *const locale = *iterator; + /* + * Search locales for a matching name, abbreviated if necessary. Stop on + * the first match found. + */ + for (iterator = GSC_AVAILABLE_LOCALES; *iterator; iterator++) { + const gsc_locale_t *const locale = *iterator; - if (sc_strncasecmp (name, locale->name, strlen (name)) == 0) - { - matched = locale; - break; - } - } + if (sc_strncasecmp(name, locale->name, strlen(name)) == 0) { + matched = locale; + break; + } + } - /* If matched, set the global locale. */ - if (matched) - gsc_locale = matched; + /* If matched, set the global locale. */ + if (matched) + gsc_locale = matched; } @@ -533,24 +545,22 @@ gsc_set_locale (const sc_char *name) * having to write transcripts as ascii. */ static void -gsc_put_char_uni (glui32 unicode, const char *ascii) -{ - /* If there is an transcript stream, temporarily disconnect it. */ - if (gsc_transcript_stream) - g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr); +gsc_put_char_uni(glui32 unicode, const char *ascii) { + /* If there is an transcript stream, temporarily disconnect it. */ + if (gsc_transcript_stream) + g_vm->glk_window_set_echo_stream(gsc_main_window, nullptr); - g_vm->glk_put_char_uni (unicode); + g_vm->glk_put_char_uni(unicode); - /* Print ascii to the transcript, then reattach it. */ - if (gsc_transcript_stream) - { - if (ascii) - g_vm->glk_put_string_stream (gsc_transcript_stream, (char *) ascii); - else - g_vm->glk_put_char_stream (gsc_transcript_stream, '?'); + /* Print ascii to the transcript, then reattach it. */ + if (gsc_transcript_stream) { + if (ascii) + g_vm->glk_put_string_stream(gsc_transcript_stream, (char *) ascii); + else + g_vm->glk_put_char_stream(gsc_transcript_stream, '?'); - g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream); - } + g_vm->glk_window_set_echo_stream(gsc_main_window, gsc_transcript_stream); + } } @@ -561,86 +571,79 @@ gsc_put_char_uni (glui32 unicode, const char *ascii) * main or the alternate codepage depending on the flag passed in. */ static void -gsc_put_char_locale (sc_char ch, - const gsc_locale_t *locale, sc_bool is_alternate) -{ - const gsc_codepages_t *codepage; - unsigned char character; - glui32 unicode; - const char *ascii; - - /* - * Select either the main or the alternate codepage for this locale, and - * retrieve the unicode and ascii representations of the character. - */ - codepage = is_alternate ? &locale->alternate : &locale->main; - character = (unsigned char) ch; - unicode = codepage->unicode[character]; - ascii = codepage->ascii[character]; - - /* - * If a unicode representation exists, use for either iso 8859-1 or, if - * possible, direct unicode output. - */ - if (unicode > 0) - { - /* - * If unicode is in the range 1-255, this value is directly equivalent - * to the iso 8859-1 representation; otherwise the character has no - * direct iso 8859-1 glyph. - */ - if (unicode < GSC_ISO_8859_EQUIVALENCE) - { - /* - * If the iso 8859-1 character is one that this Glk library will - * print exactly, print and return. We add a check here for the - * guaranteed printable characters, since some Glk libraries don't - * return the correct values for gestalt_CharOutput for these. - */ - if (unicode == '\n' - || (unicode >= GSC_MIN_PRINTABLE && unicode <= GSC_MAX_PRINTABLE) - || g_vm->glk_gestalt (gestalt_CharOutput, - unicode) == gestalt_CharOutput_ExactPrint) - { - g_vm->glk_put_char ((unsigned char) unicode); - return; - } - } - - /* - * If no usable iso 8859-1 representation, see if unicode is enabled and - * if the Glk library can print the character exactly. If yes, output - * the character that way. - * - * TODO Using unicode output currently disrupts transcript output. Any - * echo stream connected for a transcript here will be a text rather than - * a unicode stream, so probably won't output the character correctly. - * For now, if there's a transcript, we try to write ascii output. - */ - if (gsc_unicode_enabled) - { - if (g_vm->glk_gestalt (gestalt_CharOutput, - unicode) == gestalt_CharOutput_ExactPrint) - { - gsc_put_char_uni (unicode, ascii); - return; - } - } - } - - /* - * No success with iso 8859-1 or unicode, so try for an ascii substitute. - * Substitute strings use only 7-bit ascii, and so all are safe to print - * directly with Glk. - */ - if (ascii) - { - g_vm->glk_put_string ((char *) ascii); - return; - } - - /* No apparent way to output this character, so print a '?'. */ - g_vm->glk_put_char ('?'); +gsc_put_char_locale(sc_char ch, + const gsc_locale_t *locale, sc_bool is_alternate) { + const gsc_codepages_t *codepage; + unsigned char character; + glui32 unicode; + const char *ascii; + + /* + * Select either the main or the alternate codepage for this locale, and + * retrieve the unicode and ascii representations of the character. + */ + codepage = is_alternate ? &locale->alternate : &locale->main; + character = (unsigned char) ch; + unicode = codepage->unicode[character]; + ascii = codepage->ascii[character]; + + /* + * If a unicode representation exists, use for either iso 8859-1 or, if + * possible, direct unicode output. + */ + if (unicode > 0) { + /* + * If unicode is in the range 1-255, this value is directly equivalent + * to the iso 8859-1 representation; otherwise the character has no + * direct iso 8859-1 glyph. + */ + if (unicode < GSC_ISO_8859_EQUIVALENCE) { + /* + * If the iso 8859-1 character is one that this Glk library will + * print exactly, print and return. We add a check here for the + * guaranteed printable characters, since some Glk libraries don't + * return the correct values for gestalt_CharOutput for these. + */ + if (unicode == '\n' + || (unicode >= GSC_MIN_PRINTABLE && unicode <= GSC_MAX_PRINTABLE) + || g_vm->glk_gestalt(gestalt_CharOutput, + unicode) == gestalt_CharOutput_ExactPrint) { + g_vm->glk_put_char((unsigned char) unicode); + return; + } + } + + /* + * If no usable iso 8859-1 representation, see if unicode is enabled and + * if the Glk library can print the character exactly. If yes, output + * the character that way. + * + * TODO Using unicode output currently disrupts transcript output. Any + * echo stream connected for a transcript here will be a text rather than + * a unicode stream, so probably won't output the character correctly. + * For now, if there's a transcript, we try to write ascii output. + */ + if (gsc_unicode_enabled) { + if (g_vm->glk_gestalt(gestalt_CharOutput, + unicode) == gestalt_CharOutput_ExactPrint) { + gsc_put_char_uni(unicode, ascii); + return; + } + } + } + + /* + * No success with iso 8859-1 or unicode, so try for an ascii substitute. + * Substitute strings use only 7-bit ascii, and so all are safe to print + * directly with Glk. + */ + if (ascii) { + g_vm->glk_put_string((char *) ascii); + return; + } + + /* No apparent way to output this character, so print a '?'. */ + g_vm->glk_put_char('?'); } @@ -655,55 +658,49 @@ gsc_put_char_locale (sc_char ch, * Public functions for writing using the current or fallback locale. */ static void -gsc_put_char (const sc_char character) -{ - const gsc_locale_t *locale; +gsc_put_char(const sc_char character) { + const gsc_locale_t *locale; - locale = gsc_locale ? gsc_locale : gsc_fallback_locale; - gsc_put_char_locale (character, locale, FALSE); + locale = gsc_locale ? gsc_locale : gsc_fallback_locale; + gsc_put_char_locale(character, locale, FALSE); } static void -gsc_put_char_alternate (const sc_char character) -{ - const gsc_locale_t *locale; +gsc_put_char_alternate(const sc_char character) { + const gsc_locale_t *locale; - locale = gsc_locale ? gsc_locale : gsc_fallback_locale; - gsc_put_char_locale (character, locale, TRUE); + locale = gsc_locale ? gsc_locale : gsc_fallback_locale; + gsc_put_char_locale(character, locale, TRUE); } static void -gsc_put_buffer_using (const sc_char *buffer, - sc_int length, void (*putchar_function) (sc_char)) -{ - sc_int index_; +gsc_put_buffer_using(const sc_char *buffer, + sc_int length, void (*putchar_function)(sc_char)) { + sc_int index_; - for (index_ = 0; index_ < length; index_++) - putchar_function (buffer[index_]); + for (index_ = 0; index_ < length; index_++) + putchar_function(buffer[index_]); } static void -gsc_put_buffer (const sc_char *buffer, sc_int length) -{ - assert (buffer); +gsc_put_buffer(const sc_char *buffer, sc_int length) { + assert(buffer); - gsc_put_buffer_using (buffer, length, gsc_put_char); + gsc_put_buffer_using(buffer, length, gsc_put_char); } static void -gsc_put_string (const sc_char *string) -{ - assert (string); +gsc_put_string(const sc_char *string) { + assert(string); - gsc_put_buffer_using (string, strlen (string), gsc_put_char); + gsc_put_buffer_using(string, strlen(string), gsc_put_char); } static void -gsc_put_string_alternate (const sc_char *string) -{ - assert (string); +gsc_put_string_alternate(const sc_char *string) { + assert(string); - gsc_put_buffer_using (string, strlen (string), gsc_put_char_alternate); + gsc_put_buffer_using(string, strlen(string), gsc_put_char_alternate); } @@ -716,36 +713,33 @@ gsc_put_string_alternate (const sc_char *string) * available. */ static sc_char -gsc_unicode_to_locale (glui32 unicode, const gsc_locale_t *locale) -{ - const gsc_codepages_t *codepage; - sc_int character; +gsc_unicode_to_locale(glui32 unicode, const gsc_locale_t *locale) { + const gsc_codepages_t *codepage; + sc_int character; - /* Always use the main codepage for input. */ - codepage = &locale->main; + /* Always use the main codepage for input. */ + codepage = &locale->main; - /* - * Search the unicode table sequentially for the input character. This is - * inefficient, but because game input is usually not copious, excusable. - */ - for (character = 0; character < GSC_TABLE_SIZE; character++) - { - if (codepage->unicode[character] == unicode) - break; - } + /* + * Search the unicode table sequentially for the input character. This is + * inefficient, but because game input is usually not copious, excusable. + */ + for (character = 0; character < GSC_TABLE_SIZE; character++) { + if (codepage->unicode[character] == unicode) + break; + } - /* Return the character translation, or '?' if none. */ - return character < GSC_TABLE_SIZE ? (sc_char) character : '?'; + /* Return the character translation, or '?' if none. */ + return character < GSC_TABLE_SIZE ? (sc_char) character : '?'; } static void -gsc_unicode_buffer_to_locale (const glui32 *unicode, sc_int length, - sc_char *buffer, const gsc_locale_t *locale) -{ - sc_int index_; +gsc_unicode_buffer_to_locale(const glui32 *unicode, sc_int length, + sc_char *buffer, const gsc_locale_t *locale) { + sc_int index_; - for (index_ = 0; index_ < length; index_++) - buffer[index_] = gsc_unicode_to_locale (unicode[index_], locale); + for (index_ = 0; index_ < length; index_++) + buffer[index_] = gsc_unicode_to_locale(unicode[index_], locale); } @@ -756,41 +750,39 @@ gsc_unicode_buffer_to_locale (const glui32 *unicode, sc_int length, * of characters placed in the buffer. */ static sc_int -gsc_read_line_locale (sc_char *buffer, - sc_int length, const gsc_locale_t *locale) -{ - event_t event; +gsc_read_line_locale(sc_char *buffer, + sc_int length, const gsc_locale_t *locale) { + event_t event; - /* - * If we have unicode, we have to use it to ensure that characters not in - * the Latin1 locale are properly translated. - */ - if (gsc_unicode_enabled) - { - glui32 *unicode; + /* + * If we have unicode, we have to use it to ensure that characters not in + * the Latin1 locale are properly translated. + */ + if (gsc_unicode_enabled) { + glui32 *unicode; - /* - * Allocate a unicode buffer long enough to hold all the characters, - * then read in a unicode line. - */ - unicode = (glui32 *)gsc_malloc (length * sizeof (*unicode)); - g_vm->glk_request_line_event_uni (gsc_main_window, unicode, length, 0); - gsc_event_wait (evtype_LineInput, &event); + /* + * Allocate a unicode buffer long enough to hold all the characters, + * then read in a unicode line. + */ + unicode = (glui32 *)gsc_malloc(length * sizeof(*unicode)); + g_vm->glk_request_line_event_uni(gsc_main_window, unicode, length, 0); + gsc_event_wait(evtype_LineInput, &event); - /* Convert the unicode buffer out, then free it. */ - gsc_unicode_buffer_to_locale (unicode, event.val1, buffer, locale); - free (unicode); + /* Convert the unicode buffer out, then free it. */ + gsc_unicode_buffer_to_locale(unicode, event.val1, buffer, locale); + free(unicode); - /* Return the count of characters placed in the buffer. */ - return event.val1; - } + /* Return the count of characters placed in the buffer. */ + return event.val1; + } - /* No success with unicode, so fall back to standard line input. */ - g_vm->glk_request_line_event (gsc_main_window, buffer, length, 0); - gsc_event_wait (evtype_LineInput, &event); + /* No success with unicode, so fall back to standard line input. */ + g_vm->glk_request_line_event(gsc_main_window, buffer, length, 0); + gsc_event_wait(evtype_LineInput, &event); - /* Return the count of characters placed in the buffer. */ - return event.val1; + /* Return the count of characters placed in the buffer. */ + return event.val1; } @@ -800,12 +792,11 @@ gsc_read_line_locale (sc_char *buffer, * Public function for reading using the current or fallback locale. */ static sc_int -gsc_read_line (sc_char *buffer, sc_int length) -{ - const gsc_locale_t *locale; +gsc_read_line(sc_char *buffer, sc_int length) { + const gsc_locale_t *locale; - locale = gsc_locale ? gsc_locale : gsc_fallback_locale; - return gsc_read_line_locale (buffer, length, locale); + locale = gsc_locale ? gsc_locale : gsc_fallback_locale; + return gsc_read_line_locale(buffer, length, locale); } @@ -834,22 +825,19 @@ static const sc_char *const GSC_WHITESPACE = "\t\n\v\f\r "; * other than whitespace. */ static sc_bool -gsc_is_string_usable (const sc_char *string) -{ - /* If non-null, scan for any non-space character. */ - if (string) - { - sc_int index_; - - for (index_ = 0; string[index_] != '\0'; index_++) - { - if (!strchr (GSC_WHITESPACE, string[index_])) - return TRUE; - } - } +gsc_is_string_usable(const sc_char *string) { + /* If non-null, scan for any non-space character. */ + if (string) { + sc_int index_; + + for (index_ = 0; string[index_] != '\0'; index_++) { + if (!strchr(GSC_WHITESPACE, string[index_])) + return TRUE; + } + } - /* nullptr, or no characters other than whitespace. */ - return FALSE; + /* nullptr, or no characters other than whitespace. */ + return FALSE; } @@ -860,69 +848,62 @@ gsc_is_string_usable (const sc_char *string) * Glk libraries. */ static void -gsc_status_update() -{ - glui32 width, height; - uint index; - assert (gsc_status_window); - - g_vm->glk_window_get_size (gsc_status_window, &width, &height); - if (height > 0) - { - const sc_char *room; - - g_vm->glk_window_clear (gsc_status_window); - g_vm->glk_window_move_cursor (gsc_status_window, 0, 0); - g_vm->glk_set_window (gsc_status_window); - - g_vm->glk_set_style(style_User1); - for (index = 0; index < width; index++) - g_vm->glk_put_char (' '); - g_vm->glk_window_move_cursor (gsc_status_window, 0, 0); - - /* See if the game is indicating any current player room. */ - room = sc_get_game_room (gsc_game); - if (!gsc_is_string_usable (room)) - { - /* - * Player location is indeterminate, so print out a generic status, - * showing the game name and author. - */ - g_vm->glk_window_move_cursor (gsc_status_window, 1, 0); - gsc_put_string (sc_get_game_name (gsc_game)); - g_vm->glk_put_string (" | "); - gsc_put_string (sc_get_game_author (gsc_game)); - } - else - { - const sc_char *status; - char score[64]; - - /* Print the player location. */ - g_vm->glk_window_move_cursor (gsc_status_window, 1, 0); - gsc_put_string (room); - - /* Get the game's status line, or if none, format score. */ - status = sc_get_game_status_line (gsc_game); - if (!gsc_is_string_usable (status)) - { - sprintf (score, "Score: %ld", sc_get_game_score (gsc_game)); - status = score; - } - - /* Print the status line or score at window right, if it fits. */ - if (width > strlen (status) + GSC_STATUS_SLOP + 1) - { - glui32 position; - - position = width - strlen (status) - GSC_STATUS_SLOP; - g_vm->glk_window_move_cursor (gsc_status_window, position - 1, 0); - gsc_put_string (status); - } - } - - g_vm->glk_set_window (gsc_main_window); - } +gsc_status_update() { + glui32 width, height; + uint index; + assert(gsc_status_window); + + g_vm->glk_window_get_size(gsc_status_window, &width, &height); + if (height > 0) { + const sc_char *room; + + g_vm->glk_window_clear(gsc_status_window); + g_vm->glk_window_move_cursor(gsc_status_window, 0, 0); + g_vm->glk_set_window(gsc_status_window); + + g_vm->glk_set_style(style_User1); + for (index = 0; index < width; index++) + g_vm->glk_put_char(' '); + g_vm->glk_window_move_cursor(gsc_status_window, 0, 0); + + /* See if the game is indicating any current player room. */ + room = sc_get_game_room(gsc_game); + if (!gsc_is_string_usable(room)) { + /* + * Player location is indeterminate, so print out a generic status, + * showing the game name and author. + */ + g_vm->glk_window_move_cursor(gsc_status_window, 1, 0); + gsc_put_string(sc_get_game_name(gsc_game)); + g_vm->glk_put_string(" | "); + gsc_put_string(sc_get_game_author(gsc_game)); + } else { + const sc_char *status; + char score[64]; + + /* Print the player location. */ + g_vm->glk_window_move_cursor(gsc_status_window, 1, 0); + gsc_put_string(room); + + /* Get the game's status line, or if none, format score. */ + status = sc_get_game_status_line(gsc_game); + if (!gsc_is_string_usable(status)) { + sprintf(score, "Score: %ld", sc_get_game_score(gsc_game)); + status = score; + } + + /* Print the status line or score at window right, if it fits. */ + if (width > strlen(status) + GSC_STATUS_SLOP + 1) { + glui32 position; + + position = width - strlen(status) - GSC_STATUS_SLOP; + g_vm->glk_window_move_cursor(gsc_status_window, position - 1, 0); + gsc_put_string(status); + } + } + + g_vm->glk_set_window(gsc_main_window); + } } @@ -933,15 +914,14 @@ gsc_status_update() * available length. */ static void -gsc_status_safe_strcat (char *dest, size_t length, const char *src) -{ - size_t available, src_length; +gsc_status_safe_strcat(char *dest, size_t length, const char *src) { + size_t available, src_length; - /* Append only as many characters as will fit. */ - src_length = strlen (src); - available = length - strlen (dest) - 1; - if (available > 0) - strncat (dest, src, src_length < available ? src_length : available); + /* Append only as many characters as will fit. */ + src_length = strlen(src); + available = length - strlen(dest) - 1; + if (available > 0) + strncat(dest, src, src_length < available ? src_length : available); } @@ -953,48 +933,44 @@ gsc_status_safe_strcat (char *dest, size_t length, const char *src) * windowing Glk libraries. */ static void -gsc_status_print() -{ - static char current_status[GSC_STATUS_BUFFER_LENGTH + 1]; - - const sc_char *room; - - /* Do nothing if the game isn't indicating any current player room. */ - room = sc_get_game_room (gsc_game); - if (gsc_is_string_usable (room)) - { - char buffer[GSC_STATUS_BUFFER_LENGTH + 1]; - const sc_char *status; - char score[64]; - - /* Make an attempt at a status line, starting with player location. */ - strcpy (buffer, ""); - gsc_status_safe_strcat (buffer, sizeof (buffer), room); - - /* Get the game's status line, or if none, format score. */ - status = sc_get_game_status_line (gsc_game); - if (!gsc_is_string_usable (status)) - { - sprintf (score, "Score: %ld", sc_get_game_score (gsc_game)); - status = score; - } +gsc_status_print() { + static char current_status[GSC_STATUS_BUFFER_LENGTH + 1]; + + const sc_char *room; + + /* Do nothing if the game isn't indicating any current player room. */ + room = sc_get_game_room(gsc_game); + if (gsc_is_string_usable(room)) { + char buffer[GSC_STATUS_BUFFER_LENGTH + 1]; + const sc_char *status; + char score[64]; + + /* Make an attempt at a status line, starting with player location. */ + strcpy(buffer, ""); + gsc_status_safe_strcat(buffer, sizeof(buffer), room); + + /* Get the game's status line, or if none, format score. */ + status = sc_get_game_status_line(gsc_game); + if (!gsc_is_string_usable(status)) { + sprintf(score, "Score: %ld", sc_get_game_score(gsc_game)); + status = score; + } - /* Append the status line or score. */ - gsc_status_safe_strcat (buffer, sizeof (buffer), " | "); - gsc_status_safe_strcat (buffer, sizeof (buffer), status); + /* Append the status line or score. */ + gsc_status_safe_strcat(buffer, sizeof(buffer), " | "); + gsc_status_safe_strcat(buffer, sizeof(buffer), status); - /* If this matches the current saved status line, do nothing more. */ - if (strcmp (buffer, current_status) != 0) - { - /* Bracket, and output the status line buffer. */ - g_vm->glk_put_string ("[ "); - gsc_put_string (buffer); - g_vm->glk_put_string (" ]\n"); + /* If this matches the current saved status line, do nothing more. */ + if (strcmp(buffer, current_status) != 0) { + /* Bracket, and output the status line buffer. */ + g_vm->glk_put_string("[ "); + gsc_put_string(buffer); + g_vm->glk_put_string(" ]\n"); - /* Save the details of the printed status buffer. */ - strcpy (current_status, buffer); - } - } + /* Save the details of the printed status buffer. */ + strcpy(current_status, buffer); + } + } } @@ -1005,12 +981,11 @@ gsc_status_print() * or prints the status line to the main window. */ static void -gsc_status_notify() -{ - if (gsc_status_window) - gsc_status_update (); - else - gsc_status_print (); +gsc_status_notify() { + if (gsc_status_window) + gsc_status_update(); + else + gsc_status_print(); } @@ -1022,27 +997,25 @@ gsc_status_notify() * arrange events. */ static void -gsc_status_redraw() -{ - if (gsc_status_window) - { - winid_t parent; - - /* - * Rearrange the status window, without changing its actual arrangement - * in any way. This is a hack to work round incorrect window repainting - * in Xglk; it forces a complete repaint of affected windows on Glk - * window resize and arrange events, and works in part because Xglk - * doesn't check for actual arrangement changes in any way before - * invalidating its windows. The hack should be harmless to Glk - * libraries other than Xglk, moreover, we're careful to activate it - * only on resize and arrange events. - */ - parent = g_vm->glk_window_get_parent (gsc_status_window); - g_vm->glk_window_set_arrangement (parent, - winmethod_Above | winmethod_Fixed, 1, nullptr); - gsc_status_update (); - } +gsc_status_redraw() { + if (gsc_status_window) { + winid_t parent; + + /* + * Rearrange the status window, without changing its actual arrangement + * in any way. This is a hack to work round incorrect window repainting + * in Xglk; it forces a complete repaint of affected windows on Glk + * window resize and arrange events, and works in part because Xglk + * doesn't check for actual arrangement changes in any way before + * invalidating its windows. The hack should be harmless to Glk + * libraries other than Xglk, moreover, we're careful to activate it + * only on resize and arrange events. + */ + parent = g_vm->glk_window_get_parent(gsc_status_window); + g_vm->glk_window_set_arrangement(parent, + winmethod_Above | winmethod_Fixed, 1, nullptr); + gsc_status_update(); + } } @@ -1059,8 +1032,8 @@ static int gsc_help_requested = FALSE, /* Font descriptor type, encapsulating size and monospaced boolean. */ typedef struct { - sc_bool is_monospaced; - sc_int size; + sc_bool is_monospaced; + sc_int size; } gsc_font_size_t; /* Font stack and attributes for nesting tags. */ @@ -1098,29 +1071,25 @@ static const glui32 GSC_CANCEL_WAIT_1 = ' ', * help from the interpreter unless silenced. */ static void -gsc_output_register_help_request() -{ - gsc_help_requested = TRUE; +gsc_output_register_help_request() { + gsc_help_requested = TRUE; } static void -gsc_output_silence_help_hints() -{ - gsc_help_hints_silenced = TRUE; +gsc_output_silence_help_hints() { + gsc_help_hints_silenced = TRUE; } static void -gsc_output_provide_help_hint() -{ - if (gsc_help_requested && !gsc_help_hints_silenced) - { - g_vm->glk_set_style (style_Emphasized); - g_vm->glk_put_string ("[Try 'glk help' for help on special interpreter" - " commands]\n"); +gsc_output_provide_help_hint() { + if (gsc_help_requested && !gsc_help_hints_silenced) { + g_vm->glk_set_style(style_Emphasized); + g_vm->glk_put_string("[Try 'glk help' for help on special interpreter" + " commands]\n"); - gsc_help_requested = FALSE; - g_vm->glk_set_style (style_Normal); - } + gsc_help_requested = FALSE; + g_vm->glk_set_style(style_Normal); + } } @@ -1129,67 +1098,58 @@ gsc_output_provide_help_hint() * * Set a Glk style based on the top of the font stack and attributes. */ -static void gsc_set_glk_style() -{ - sc_bool is_monospaced; - sc_int font_size; - - /* Get the current font stack top, or default value. */ - if (gsc_font_index > 0) - { - is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; - font_size = gsc_font_stack[gsc_font_index - 1].size; - } - else - { - is_monospaced = FALSE; - font_size = GSC_DEFAULT_FONT_SIZE; - } - - /* - * Map the font and current attributes into a Glk style. Because Glk styles - * aren't cumulative this has to be done by precedences. - */ - if (is_monospaced) - { - /* - * No matter the size or attributes, if monospaced use Preformatted - * style, as it's all we have. - */ - g_vm->glk_set_style (style_Preformatted); - } - else - { - /* - * For large and medium point sizes, use Header or Subheader styles - * respectively. - */ - if (font_size >= GSC_LARGE_FONT_SIZE) - g_vm->glk_set_style (style_Header); - else if (font_size >= GSC_MEDIUM_FONT_SIZE) - g_vm->glk_set_style (style_Subheader); - else - { - /* - * For bold, use Subheader; for italics, underline, or secondary - * color, use Emphasized. - */ - if (gsc_attribute_bold > 0) - g_vm->glk_set_style (style_Subheader); - else if (gsc_attribute_italic > 0 - || gsc_attribute_underline > 0 - || gsc_attribute_secondary_color > 0) - g_vm->glk_set_style (style_Emphasized); - else - { - /* - * There's nothing special about this text, so drop down to - * Normal style. - */ - g_vm->glk_set_style (style_Normal); - } - } - } +static void gsc_set_glk_style() { + sc_bool is_monospaced; + sc_int font_size; + + /* Get the current font stack top, or default value. */ + if (gsc_font_index > 0) { + is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; + font_size = gsc_font_stack[gsc_font_index - 1].size; + } else { + is_monospaced = FALSE; + font_size = GSC_DEFAULT_FONT_SIZE; + } + + /* + * Map the font and current attributes into a Glk style. Because Glk styles + * aren't cumulative this has to be done by precedences. + */ + if (is_monospaced) { + /* + * No matter the size or attributes, if monospaced use Preformatted + * style, as it's all we have. + */ + g_vm->glk_set_style(style_Preformatted); + } else { + /* + * For large and medium point sizes, use Header or Subheader styles + * respectively. + */ + if (font_size >= GSC_LARGE_FONT_SIZE) + g_vm->glk_set_style(style_Header); + else if (font_size >= GSC_MEDIUM_FONT_SIZE) + g_vm->glk_set_style(style_Subheader); + else { + /* + * For bold, use Subheader; for italics, underline, or secondary + * color, use Emphasized. + */ + if (gsc_attribute_bold > 0) + g_vm->glk_set_style(style_Subheader); + else if (gsc_attribute_italic > 0 + || gsc_attribute_underline > 0 + || gsc_attribute_secondary_color > 0) + g_vm->glk_set_style(style_Emphasized); + else { + /* + * There's nothing special about this text, so drop down to + * Normal style. + */ + g_vm->glk_set_style(style_Normal); + } + } + } } @@ -1201,83 +1161,74 @@ static void gsc_set_glk_style() * font tag. Set the appropriate Glk style. */ static void -gsc_handle_font_tag (const sc_char *argument) -{ - /* Ignore the call on stack overrun. */ - if (gsc_font_index < GSC_MAX_STYLE_NESTING) - { - sc_char *lower, *face, *size; - sc_bool is_monospaced; - sc_int index_, font_size; - - /* Get the current top of stack, or default on empty stack. */ - if (gsc_font_index > 0) - { - is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; - font_size = gsc_font_stack[gsc_font_index - 1].size; - } - else - { - is_monospaced = FALSE; - font_size = GSC_DEFAULT_FONT_SIZE; - } - - /* Copy and convert argument to all lowercase. */ - lower = (sc_char *)gsc_malloc (strlen (argument) + 1); - strcpy (lower, argument); - for (index_ = 0; lower[index_] != '\0'; index_++) - lower[index_] = g_vm->glk_char_to_lower (lower[index_]); - - /* Find any face= portion of the tag argument. */ - face = strstr (lower, "face="); - if (face) - { - /* - * There may be plenty of monospaced fonts, but we do only courier - * and terminal. - */ - is_monospaced = strncmp (face, "face=\"courier\"", 14) == 0 - || strncmp (face, "face=\"terminal\"", 15) == 0; - } - - /* Find the size= portion of the tag argument. */ - size = strstr (lower, "size="); - if (size) - { - sc_uint value; - - /* Deal with incremental and absolute sizes. */ - if (strncmp (size, "size=+", 6) == 0 - && sscanf (size, "size=+%lu", &value) == 1) - font_size += value; - else if (strncmp (size, "size=-", 6) == 0 - && sscanf (size, "size=-%lu", &value) == 1) - font_size -= value; - else if (sscanf (size, "size=%lu", &value) == 1) - font_size = value; - } - - /* Done with tag argument copy. */ - free (lower); - - /* - * Push the new font setting onto the font stack, and set Glk style. - */ - gsc_font_stack[gsc_font_index].is_monospaced = is_monospaced; - gsc_font_stack[gsc_font_index++].size = font_size; - gsc_set_glk_style(); - } +gsc_handle_font_tag(const sc_char *argument) { + /* Ignore the call on stack overrun. */ + if (gsc_font_index < GSC_MAX_STYLE_NESTING) { + sc_char *lower, *face, *size; + sc_bool is_monospaced; + sc_int index_, font_size; + + /* Get the current top of stack, or default on empty stack. */ + if (gsc_font_index > 0) { + is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; + font_size = gsc_font_stack[gsc_font_index - 1].size; + } else { + is_monospaced = FALSE; + font_size = GSC_DEFAULT_FONT_SIZE; + } + + /* Copy and convert argument to all lowercase. */ + lower = (sc_char *)gsc_malloc(strlen(argument) + 1); + strcpy(lower, argument); + for (index_ = 0; lower[index_] != '\0'; index_++) + lower[index_] = g_vm->glk_char_to_lower(lower[index_]); + + /* Find any face= portion of the tag argument. */ + face = strstr(lower, "face="); + if (face) { + /* + * There may be plenty of monospaced fonts, but we do only courier + * and terminal. + */ + is_monospaced = strncmp(face, "face=\"courier\"", 14) == 0 + || strncmp(face, "face=\"terminal\"", 15) == 0; + } + + /* Find the size= portion of the tag argument. */ + size = strstr(lower, "size="); + if (size) { + sc_uint value; + + /* Deal with incremental and absolute sizes. */ + if (strncmp(size, "size=+", 6) == 0 + && sscanf(size, "size=+%lu", &value) == 1) + font_size += value; + else if (strncmp(size, "size=-", 6) == 0 + && sscanf(size, "size=-%lu", &value) == 1) + font_size -= value; + else if (sscanf(size, "size=%lu", &value) == 1) + font_size = value; + } + + /* Done with tag argument copy. */ + free(lower); + + /* + * Push the new font setting onto the font stack, and set Glk style. + */ + gsc_font_stack[gsc_font_index].is_monospaced = is_monospaced; + gsc_font_stack[gsc_font_index++].size = font_size; + gsc_set_glk_style(); + } } static void -gsc_handle_endfont_tag() -{ - /* Unless underrun, pop the font stack and set Glk style. */ - if (gsc_font_index > 0) - { - gsc_font_index--; - gsc_set_glk_style(); - } +gsc_handle_endfont_tag() { + /* Unless underrun, pop the font stack and set Glk style. */ + if (gsc_font_index > 0) { + gsc_font_index--; + gsc_set_glk_style(); + } } @@ -1288,60 +1239,56 @@ gsc_handle_endfont_tag() * tag. Set the appropriate Glk style. */ static void -gsc_handle_attribute_tag (sc_int tag) -{ - /* - * Increment the required attribute nesting counter, and set Glk style. - */ - switch (tag) - { - case SC_TAG_BOLD: - gsc_attribute_bold++; - break; - case SC_TAG_ITALICS: - gsc_attribute_italic++; - break; - case SC_TAG_UNDERLINE: - gsc_attribute_underline++; - break; - case SC_TAG_COLOR: - gsc_attribute_secondary_color++; - break; - default: - break; - } - gsc_set_glk_style(); +gsc_handle_attribute_tag(sc_int tag) { + /* + * Increment the required attribute nesting counter, and set Glk style. + */ + switch (tag) { + case SC_TAG_BOLD: + gsc_attribute_bold++; + break; + case SC_TAG_ITALICS: + gsc_attribute_italic++; + break; + case SC_TAG_UNDERLINE: + gsc_attribute_underline++; + break; + case SC_TAG_COLOR: + gsc_attribute_secondary_color++; + break; + default: + break; + } + gsc_set_glk_style(); } static void -gsc_handle_endattribute_tag (sc_int tag) -{ - /* - * Decrement the required attribute nesting counter, unless underrun, and - * set Glk style. - */ - switch (tag) - { - case SC_TAG_ENDBOLD: - if (gsc_attribute_bold > 0) - gsc_attribute_bold--; - break; - case SC_TAG_ENDITALICS: - if (gsc_attribute_italic > 0) - gsc_attribute_italic--; - break; - case SC_TAG_ENDUNDERLINE: - if (gsc_attribute_underline > 0) - gsc_attribute_underline--; - break; - case SC_TAG_ENDCOLOR: - if (gsc_attribute_secondary_color > 0) - gsc_attribute_secondary_color--; - break; - default: - break; - } - gsc_set_glk_style(); +gsc_handle_endattribute_tag(sc_int tag) { + /* + * Decrement the required attribute nesting counter, unless underrun, and + * set Glk style. + */ + switch (tag) { + case SC_TAG_ENDBOLD: + if (gsc_attribute_bold > 0) + gsc_attribute_bold--; + break; + case SC_TAG_ENDITALICS: + if (gsc_attribute_italic > 0) + gsc_attribute_italic--; + break; + case SC_TAG_ENDUNDERLINE: + if (gsc_attribute_underline > 0) + gsc_attribute_underline--; + break; + case SC_TAG_ENDCOLOR: + if (gsc_attribute_secondary_color > 0) + gsc_attribute_secondary_color--; + break; + default: + break; + } + gsc_set_glk_style(); } @@ -1351,62 +1298,55 @@ gsc_handle_endattribute_tag (sc_int tag) * If Glk offers timers, delay for the requested period. Otherwise, this * function does nothing. */ -static void gsc_handle_wait_tag(const sc_char *argument) -{ - double delay = 0.0; - - /* Ignore the wait tag if the Glk doesn't have timers. */ - if (!g_vm->glk_gestalt (gestalt_Timer, 0)) - return; - - /* Determine the delay time, and convert to milliseconds. */ - if (sscanf (argument, "%lf", &delay) == 1 && delay > 0.0) - { - glui32 milliseconds, timeout; - - /* - * Work with timeouts at 1/10 of the wait period, to minimize Glk - * timer jitter. Allow the timeout to be canceled by keypress, as a - * user convenience. - */ - milliseconds = (glui32) (delay * GSC_MILLISECONDS_PER_SECOND); - timeout = milliseconds / GSC_TIMEOUTS_COUNT; - if (timeout > 0) - { - glui32 delayed; - sc_bool is_completed; - - /* Request timer events, and let a keypress cancel the wait. */ - g_vm->glk_request_char_event (gsc_main_window); - g_vm->glk_request_timer_events (timeout); - - /* Loop until delay completed or canceled by a keypress. */ - is_completed = TRUE; - for (delayed = 0; delayed < milliseconds; delayed += timeout) - { - event_t event; - - gsc_event_wait_2 (evtype_CharInput, evtype_Timer, &event); - if (event.type == evtype_CharInput) - { - /* Cancel the delay, or reissue the input request. */ - if (event.val1 == GSC_CANCEL_WAIT_1 - || event.val1 == GSC_CANCEL_WAIT_2) - { - is_completed = FALSE; - break; - } - else - g_vm->glk_request_char_event (gsc_main_window); - } - } - - /* Cancel any pending character input, and stop timers. */ - if (is_completed) - g_vm->glk_cancel_char_event (gsc_main_window); - g_vm->glk_request_timer_events (0); - } - } +static void gsc_handle_wait_tag(const sc_char *argument) { + double delay = 0.0; + + /* Ignore the wait tag if the Glk doesn't have timers. */ + if (!g_vm->glk_gestalt(gestalt_Timer, 0)) + return; + + /* Determine the delay time, and convert to milliseconds. */ + if (sscanf(argument, "%lf", &delay) == 1 && delay > 0.0) { + glui32 milliseconds, timeout; + + /* + * Work with timeouts at 1/10 of the wait period, to minimize Glk + * timer jitter. Allow the timeout to be canceled by keypress, as a + * user convenience. + */ + milliseconds = (glui32)(delay * GSC_MILLISECONDS_PER_SECOND); + timeout = milliseconds / GSC_TIMEOUTS_COUNT; + if (timeout > 0) { + glui32 delayed; + sc_bool is_completed; + + /* Request timer events, and let a keypress cancel the wait. */ + g_vm->glk_request_char_event(gsc_main_window); + g_vm->glk_request_timer_events(timeout); + + /* Loop until delay completed or canceled by a keypress. */ + is_completed = TRUE; + for (delayed = 0; delayed < milliseconds; delayed += timeout) { + event_t event; + + gsc_event_wait_2(evtype_CharInput, evtype_Timer, &event); + if (event.type == evtype_CharInput) { + /* Cancel the delay, or reissue the input request. */ + if (event.val1 == GSC_CANCEL_WAIT_1 + || event.val1 == GSC_CANCEL_WAIT_2) { + is_completed = FALSE; + break; + } else + g_vm->glk_request_char_event(gsc_main_window); + } + } + + /* Cancel any pending character input, and stop timers. */ + if (is_completed) + g_vm->glk_cancel_char_event(gsc_main_window); + g_vm->glk_request_timer_events(0); + } + } } @@ -1417,15 +1357,14 @@ static void gsc_handle_wait_tag(const sc_char *argument) * style. */ static void -gsc_reset_glk_style() -{ - /* Reset the font stack and attributes, and set a normal style. */ - gsc_font_index = 0; - gsc_attribute_bold = 0; - gsc_attribute_italic = 0; - gsc_attribute_underline = 0; - gsc_attribute_secondary_color = 0; - gsc_set_glk_style(); +gsc_reset_glk_style() { + /* Reset the font stack and attributes, and set a normal style. */ + gsc_font_index = 0; + gsc_attribute_bold = 0; + gsc_attribute_italic = 0; + gsc_attribute_underline = 0; + gsc_attribute_secondary_color = 0; + gsc_set_glk_style(); } @@ -1436,88 +1375,84 @@ gsc_reset_glk_style() * here; several are ignored. */ void -os_print_tag (sc_int tag, const sc_char *argument) -{ - event_t event; - assert (argument); - - switch (tag) - { - case SC_TAG_CLS: - /* Clear the main text display window. */ - g_vm->glk_window_clear (gsc_main_window); - break; - - case SC_TAG_FONT: - /* Handle with specific tag handler function. */ - gsc_handle_font_tag (argument); - break; - - case SC_TAG_ENDFONT: - /* Handle with specific endtag handler function. */ - gsc_handle_endfont_tag (); - break; - - case SC_TAG_BOLD: - case SC_TAG_ITALICS: - case SC_TAG_UNDERLINE: - case SC_TAG_COLOR: - /* Handle with common attribute tag handler function. */ - gsc_handle_attribute_tag (tag); - break; - - case SC_TAG_ENDBOLD: - case SC_TAG_ENDITALICS: - case SC_TAG_ENDUNDERLINE: - case SC_TAG_ENDCOLOR: - /* Handle with common attribute endtag handler function. */ - gsc_handle_endattribute_tag (tag); - break; - - case SC_TAG_CENTER: - case SC_TAG_RIGHT: - case SC_TAG_ENDCENTER: - case SC_TAG_ENDRIGHT: - /* - * We don't center or justify text, but so that things look right we do - * want a newline on starting or ending such a section. - */ - g_vm->glk_put_char ('\n'); - break; - - case SC_TAG_WAIT: - /* - * Update the status line now only if it has its own window, then - * handle with a specialized handler. - */ - if (gsc_status_window) - gsc_status_notify (); - gsc_handle_wait_tag (argument); - break; - - case SC_TAG_WAITKEY: - /* - * If reading an input log, ignore; it disrupts replay. Write a newline - * to separate off any unterminated game output instead. - */ - if (!gsc_readlog_stream) - { - /* Update the status line now only if it has its own window. */ - if (gsc_status_window) - gsc_status_notify (); - - /* Request a character event, and wait for it to be filled. */ - g_vm->glk_request_char_event (gsc_main_window); - gsc_event_wait (evtype_CharInput, &event); - } - else - g_vm->glk_put_char ('\n'); - break; - - default: - /* Ignore unimplemented and unknown tags. */ - break; - } +os_print_tag(sc_int tag, const sc_char *argument) { + event_t event; + assert(argument); + + switch (tag) { + case SC_TAG_CLS: + /* Clear the main text display window. */ + g_vm->glk_window_clear(gsc_main_window); + break; + + case SC_TAG_FONT: + /* Handle with specific tag handler function. */ + gsc_handle_font_tag(argument); + break; + + case SC_TAG_ENDFONT: + /* Handle with specific endtag handler function. */ + gsc_handle_endfont_tag(); + break; + + case SC_TAG_BOLD: + case SC_TAG_ITALICS: + case SC_TAG_UNDERLINE: + case SC_TAG_COLOR: + /* Handle with common attribute tag handler function. */ + gsc_handle_attribute_tag(tag); + break; + + case SC_TAG_ENDBOLD: + case SC_TAG_ENDITALICS: + case SC_TAG_ENDUNDERLINE: + case SC_TAG_ENDCOLOR: + /* Handle with common attribute endtag handler function. */ + gsc_handle_endattribute_tag(tag); + break; + + case SC_TAG_CENTER: + case SC_TAG_RIGHT: + case SC_TAG_ENDCENTER: + case SC_TAG_ENDRIGHT: + /* + * We don't center or justify text, but so that things look right we do + * want a newline on starting or ending such a section. + */ + g_vm->glk_put_char('\n'); + break; + + case SC_TAG_WAIT: + /* + * Update the status line now only if it has its own window, then + * handle with a specialized handler. + */ + if (gsc_status_window) + gsc_status_notify(); + gsc_handle_wait_tag(argument); + break; + + case SC_TAG_WAITKEY: + /* + * If reading an input log, ignore; it disrupts replay. Write a newline + * to separate off any unterminated game output instead. + */ + if (!gsc_readlog_stream) { + /* Update the status line now only if it has its own window. */ + if (gsc_status_window) + gsc_status_notify(); + + /* Request a character event, and wait for it to be filled. */ + g_vm->glk_request_char_event(gsc_main_window); + gsc_event_wait(evtype_CharInput, &event); + } else + g_vm->glk_put_char('\n'); + break; + + default: + /* Ignore unimplemented and unknown tags. */ + break; + } } @@ -1527,30 +1462,30 @@ os_print_tag (sc_int tag, const sc_char *argument) * Print a text string to the main output window. */ void os_print_string(const sc_char *string) { - sc_bool is_monospaced; - assert (string); - assert (g_vm->glk_stream_get_current ()); - - /* - * Get the monospace font setting from the current top of stack, or - * default on empty stack. If set, we may need to use an alternative - * function to write this string. - */ - if (gsc_font_index > 0) - is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; - else - is_monospaced = FALSE; - - /* - * The main window should always be the currently set window at this point, - * so we never be attempting monospaced output to the status window. - * Nevertheless, check anyway. - */ - if (is_monospaced - && g_vm->glk_stream_get_current () == g_vm->glk_window_get_stream (gsc_main_window)) - gsc_put_string_alternate (string); - else - gsc_put_string (string); + sc_bool is_monospaced; + assert(string); + assert(g_vm->glk_stream_get_current()); + + /* + * Get the monospace font setting from the current top of stack, or + * default on empty stack. If set, we may need to use an alternative + * function to write this string. + */ + if (gsc_font_index > 0) + is_monospaced = gsc_font_stack[gsc_font_index - 1].is_monospaced; + else + is_monospaced = FALSE; + + /* + * The main window should always be the currently set window at this point, + * so we never be attempting monospaced output to the status window. + * Nevertheless, check anyway. + */ + if (is_monospaced + && g_vm->glk_stream_get_current() == g_vm->glk_window_get_stream(gsc_main_window)) + gsc_put_string_alternate(string); + else + gsc_put_string(string); } @@ -1561,12 +1496,11 @@ void os_print_string(const sc_char *string) { * dedicated debugging window attempted. */ void -os_print_string_debug (const sc_char *string) -{ - assert (string); - assert (g_vm->glk_stream_get_current ()); +os_print_string_debug(const sc_char *string) { + assert(string); + assert(g_vm->glk_stream_get_current()); - gsc_put_string (string); + gsc_put_string(string); } @@ -1583,53 +1517,46 @@ os_print_string_debug (const sc_char *string) * string is one that hints that it's from the interpreter, not the game. */ static void -gsc_styled_string (glui32 style, const char *message) -{ - assert (message); +gsc_styled_string(glui32 style, const char *message) { + assert(message); - g_vm->glk_set_style (style); - g_vm->glk_put_string ((char *) message); - g_vm->glk_set_style (style_Normal); + g_vm->glk_set_style(style); + g_vm->glk_put_string((char *) message); + g_vm->glk_set_style(style_Normal); } static void -gsc_styled_char (glui32 style, char c) -{ - char buffer[2]; +gsc_styled_char(glui32 style, char c) { + char buffer[2]; - buffer[0] = c; - buffer[1] = '\0'; - gsc_styled_string (style, buffer); + buffer[0] = c; + buffer[1] = '\0'; + gsc_styled_string(style, buffer); } static void -gsc_standout_string (const char *message) -{ - gsc_styled_string (style_Emphasized, message); +gsc_standout_string(const char *message) { + gsc_styled_string(style_Emphasized, message); } static void -gsc_standout_char (char c) -{ - gsc_styled_char (style_Emphasized, c); +gsc_standout_char(char c) { + gsc_styled_char(style_Emphasized, c); } static void -gsc_normal_string (const char *message) -{ - gsc_styled_string (style_Normal, message); +gsc_normal_string(const char *message) { + gsc_styled_string(style_Normal, message); } static void -gsc_normal_char (char c) -{ - gsc_styled_char (style_Normal, c); +gsc_normal_char(char c) { + gsc_styled_char(style_Normal, c); } static void -gsc_header_string (const char *message) -{ - gsc_styled_string (style_Header, message); +gsc_header_string(const char *message) { + gsc_styled_string(style_Header, message); } @@ -1641,60 +1568,53 @@ gsc_header_string (const char *message) * it's sort of good enough for the moment. */ void -os_display_hints (sc_game game) -{ - sc_game_hint hint; - sc_int refused; - - /* For each hint, print the question, and confirm hint display. */ - refused = 0; - for (hint = sc_get_first_game_hint (game); - hint; hint = sc_get_next_game_hint (game, hint)) - { - const sc_char *hint_question, *hint_text; - - /* If enough refusals, offer a way out of the loop. */ - if (refused >= GSC_HINT_REFUSAL_LIMIT) - { - if (!os_confirm (GSC_CONF_CONTINUE_HINTS)) - break; - refused = 0; - } - - /* Pop the question. */ - hint_question = sc_get_game_hint_question (game, hint); - gsc_normal_char ('\n'); - gsc_standout_string (hint_question); - gsc_normal_char ('\n'); - - /* Print the subtle hint, or on to the next hint. */ - hint_text = sc_get_game_subtle_hint (game, hint); - if (hint_text) - { - if (!os_confirm (GSC_CONF_SUBTLE_HINT)) - { - refused++; - continue; - } - gsc_normal_char ('\n'); - gsc_standout_string (hint_text); - gsc_normal_string ("\n\n"); - } - - /* Print the less than subtle hint, or on to the next hint. */ - hint_text = sc_get_game_unsubtle_hint (game, hint); - if (hint_text) - { - if (!os_confirm (GSC_CONF_UNSUBTLE_HINT)) - { - refused++; - continue; - } - gsc_normal_char ('\n'); - gsc_standout_string (hint_text); - gsc_normal_string ("\n\n"); - } - } +os_display_hints(sc_game game) { + sc_game_hint hint; + sc_int refused; + + /* For each hint, print the question, and confirm hint display. */ + refused = 0; + for (hint = sc_get_first_game_hint(game); + hint; hint = sc_get_next_game_hint(game, hint)) { + const sc_char *hint_question, *hint_text; + + /* If enough refusals, offer a way out of the loop. */ + if (refused >= GSC_HINT_REFUSAL_LIMIT) { + if (!os_confirm(GSC_CONF_CONTINUE_HINTS)) + break; + refused = 0; + } + + /* Pop the question. */ + hint_question = sc_get_game_hint_question(game, hint); + gsc_normal_char('\n'); + gsc_standout_string(hint_question); + gsc_normal_char('\n'); + + /* Print the subtle hint, or on to the next hint. */ + hint_text = sc_get_game_subtle_hint(game, hint); + if (hint_text) { + if (!os_confirm(GSC_CONF_SUBTLE_HINT)) { + refused++; + continue; + } + gsc_normal_char('\n'); + gsc_standout_string(hint_text); + gsc_normal_string("\n\n"); + } + + /* Print the less than subtle hint, or on to the next hint. */ + hint_text = sc_get_game_unsubtle_hint(game, hint); + if (hint_text) { + if (!os_confirm(GSC_CONF_UNSUBTLE_HINT)) { + refused++; + continue; + } + gsc_normal_char('\n'); + gsc_standout_string(hint_text); + gsc_normal_string("\n\n"); + } + } } @@ -1709,21 +1629,19 @@ os_display_hints (sc_game game) * Stub functions. The unused variables defeat gcc warnings. */ void -os_play_sound (const sc_char *filepath, - sc_int offset, sc_int length, sc_bool is_looping) -{ - const sc_char *unused1; - sc_int unused2, unused3; - sc_bool unused4; - unused1 = filepath; - unused2 = offset; - unused3 = length; - unused4 = is_looping; +os_play_sound(const sc_char *filepath, + sc_int offset, sc_int length, sc_bool is_looping) { + const sc_char *unused1; + sc_int unused2, unused3; + sc_bool unused4; + unused1 = filepath; + unused2 = offset; + unused3 = length; + unused4 = is_looping; } void -os_stop_sound() -{ +os_stop_sound() { } @@ -1742,43 +1660,40 @@ os_stop_sound() static int gsclinux_graphics_enabled = TRUE; static char *gsclinux_game_file = nullptr; void -os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length) -{ - const sc_char *unused1; - unused1 = filepath; - - if (length > 0 - && gsclinux_graphics_enabled && g_vm->glk_gestalt (gestalt_Graphics, 0)) - { - sc_char *buffer; - - /* - * Try to extract data with dd. Assuming that works, background xv to - * display the image, then background a job to delay ten seconds and - * then delete the temporary file containing the image. Systems lacking - * xv can usually use a small script, named xv, to invoke eog or an - * alternative image display binary. Not exactly finessed. - */ - assert (gsclinux_game_file); - buffer = gsc_malloc (strlen (gsclinux_game_file) + 128); - sprintf (buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k" - " of=/tmp/scare.jpg 2>/dev/null", - gsclinux_game_file, offset, length); - system (buffer); - free (buffer); - system ("xv /tmp/scare.jpg >/dev/null 2>&1 &"); - system ("( sleep 10; rm /tmp/scare.jpg ) >/dev/null 2>&1 &"); - } +os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) { + const sc_char *unused1; + unused1 = filepath; + + if (length > 0 + && gsclinux_graphics_enabled && g_vm->glk_gestalt(gestalt_Graphics, 0)) { + sc_char *buffer; + + /* + * Try to extract data with dd. Assuming that works, background xv to + * display the image, then background a job to delay ten seconds and + * then delete the temporary file containing the image. Systems lacking + * xv can usually use a small script, named xv, to invoke eog or an + * alternative image display binary. Not exactly finessed. + */ + assert(gsclinux_game_file); + buffer = gsc_malloc(strlen(gsclinux_game_file) + 128); + sprintf(buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k" + " of=/tmp/scare.jpg 2>/dev/null", + gsclinux_game_file, offset, length); + system(buffer); + free(buffer); + system("xv /tmp/scare.jpg >/dev/null 2>&1 &"); + system("( sleep 10; rm /tmp/scare.jpg ) >/dev/null 2>&1 &"); + } } #else void -os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length) -{ - const sc_char *unused1; - sc_int unused2, unused3; - unused1 = filepath; - unused2 = offset; - unused3 = length; +os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) { + const sc_char *unused1; + sc_int unused2, unused3; + unused1 = filepath; + unused2 = offset; + unused3 = length; } #endif @@ -1793,74 +1708,65 @@ os_show_graphic (const sc_char *filepath, sc_int offset, sc_int length) * Turn game output scripting (logging) on and off. */ static void -gsc_command_script (const char *argument) -{ - assert (argument); - - if (sc_strcasecmp (argument, "on") == 0) - { - frefid_t fileref; - - if (gsc_transcript_stream) - { - gsc_normal_string ("Glk transcript is already on.\n"); - return; - } - - fileref = g_vm->glk_fileref_create_by_prompt (fileusage_Transcript - | fileusage_TextMode, - filemode_WriteAppend, 0); - if (!fileref) - { - gsc_standout_string ("Glk transcript failed.\n"); - return; - } - - gsc_transcript_stream = g_vm->glk_stream_open_file (fileref, - filemode_WriteAppend, 0); - g_vm->glk_fileref_destroy (fileref); - if (!gsc_transcript_stream) - { - gsc_standout_string ("Glk transcript failed.\n"); - return; - } - - g_vm->glk_window_set_echo_stream (gsc_main_window, gsc_transcript_stream); - - gsc_normal_string ("Glk transcript is now on.\n"); - } - - else if (sc_strcasecmp (argument, "off") == 0) - { - if (!gsc_transcript_stream) - { - gsc_normal_string ("Glk transcript is already off.\n"); - return; - } - - g_vm->glk_stream_close (gsc_transcript_stream, nullptr); - gsc_transcript_stream = nullptr; - - g_vm->glk_window_set_echo_stream (gsc_main_window, nullptr); - - gsc_normal_string ("Glk transcript is now off.\n"); - } - - else if (strlen (argument) == 0) - { - gsc_normal_string ("Glk transcript is "); - gsc_normal_string (gsc_transcript_stream ? "on" : "off"); - gsc_normal_string (".\n"); - } - - else - { - gsc_normal_string ("Glk transcript can be "); - gsc_standout_string ("on"); - gsc_normal_string (", or "); - gsc_standout_string ("off"); - gsc_normal_string (".\n"); - } +gsc_command_script(const char *argument) { + assert(argument); + + if (sc_strcasecmp(argument, "on") == 0) { + frefid_t fileref; + + if (gsc_transcript_stream) { + gsc_normal_string("Glk transcript is already on.\n"); + return; + } + + fileref = g_vm->glk_fileref_create_by_prompt(fileusage_Transcript + | fileusage_TextMode, + filemode_WriteAppend, 0); + if (!fileref) { + gsc_standout_string("Glk transcript failed.\n"); + return; + } + + gsc_transcript_stream = g_vm->glk_stream_open_file(fileref, + filemode_WriteAppend, 0); + g_vm->glk_fileref_destroy(fileref); + if (!gsc_transcript_stream) { + gsc_standout_string("Glk transcript failed.\n"); + return; + } + + g_vm->glk_window_set_echo_stream(gsc_main_window, gsc_transcript_stream); + + gsc_normal_string("Glk transcript is now on.\n"); + } + + else if (sc_strcasecmp(argument, "off") == 0) { + if (!gsc_transcript_stream) { + gsc_normal_string("Glk transcript is already off.\n"); + return; + } + + g_vm->glk_stream_close(gsc_transcript_stream, nullptr); + gsc_transcript_stream = nullptr; + + g_vm->glk_window_set_echo_stream(gsc_main_window, nullptr); + + gsc_normal_string("Glk transcript is now off.\n"); + } + + else if (strlen(argument) == 0) { + gsc_normal_string("Glk transcript is "); + gsc_normal_string(gsc_transcript_stream ? "on" : "off"); + gsc_normal_string(".\n"); + } + + else { + gsc_normal_string("Glk transcript can be "); + gsc_standout_string("on"); + gsc_normal_string(", or "); + gsc_standout_string("off"); + gsc_normal_string(".\n"); + } } @@ -1870,70 +1776,61 @@ gsc_command_script (const char *argument) * Turn game input logging on and off. */ static void -gsc_command_inputlog (const char *argument) -{ - assert (argument); - - if (sc_strcasecmp (argument, "on") == 0) - { - frefid_t fileref; - - if (gsc_inputlog_stream) - { - gsc_normal_string ("Glk input logging is already on.\n"); - return; - } - - fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord - | fileusage_BinaryMode, - filemode_WriteAppend, 0); - if (!fileref) - { - gsc_standout_string ("Glk input logging failed.\n"); - return; - } - - gsc_inputlog_stream = g_vm->glk_stream_open_file (fileref, - filemode_WriteAppend, 0); - g_vm->glk_fileref_destroy (fileref); - if (!gsc_inputlog_stream) - { - gsc_standout_string ("Glk input logging failed.\n"); - return; - } - - gsc_normal_string ("Glk input logging is now on.\n"); - } - - else if (sc_strcasecmp (argument, "off") == 0) - { - if (!gsc_inputlog_stream) - { - gsc_normal_string ("Glk input logging is already off.\n"); - return; - } - - g_vm->glk_stream_close (gsc_inputlog_stream, nullptr); - gsc_inputlog_stream = nullptr; - - gsc_normal_string ("Glk input log is now off.\n"); - } - - else if (strlen (argument) == 0) - { - gsc_normal_string ("Glk input logging is "); - gsc_normal_string (gsc_inputlog_stream ? "on" : "off"); - gsc_normal_string (".\n"); - } - - else - { - gsc_normal_string ("Glk input logging can be "); - gsc_standout_string ("on"); - gsc_normal_string (", or "); - gsc_standout_string ("off"); - gsc_normal_string (".\n"); - } +gsc_command_inputlog(const char *argument) { + assert(argument); + + if (sc_strcasecmp(argument, "on") == 0) { + frefid_t fileref; + + if (gsc_inputlog_stream) { + gsc_normal_string("Glk input logging is already on.\n"); + return; + } + + fileref = g_vm->glk_fileref_create_by_prompt(fileusage_InputRecord + | fileusage_BinaryMode, + filemode_WriteAppend, 0); + if (!fileref) { + gsc_standout_string("Glk input logging failed.\n"); + return; + } + + gsc_inputlog_stream = g_vm->glk_stream_open_file(fileref, + filemode_WriteAppend, 0); + g_vm->glk_fileref_destroy(fileref); + if (!gsc_inputlog_stream) { + gsc_standout_string("Glk input logging failed.\n"); + return; + } + + gsc_normal_string("Glk input logging is now on.\n"); + } + + else if (sc_strcasecmp(argument, "off") == 0) { + if (!gsc_inputlog_stream) { + gsc_normal_string("Glk input logging is already off.\n"); + return; + } + + g_vm->glk_stream_close(gsc_inputlog_stream, nullptr); + gsc_inputlog_stream = nullptr; + + gsc_normal_string("Glk input log is now off.\n"); + } + + else if (strlen(argument) == 0) { + gsc_normal_string("Glk input logging is "); + gsc_normal_string(gsc_inputlog_stream ? "on" : "off"); + gsc_normal_string(".\n"); + } + + else { + gsc_normal_string("Glk input logging can be "); + gsc_standout_string("on"); + gsc_normal_string(", or "); + gsc_standout_string("off"); + gsc_normal_string(".\n"); + } } @@ -1943,76 +1840,66 @@ gsc_command_inputlog (const char *argument) * Set the game input log, to read input from a file. */ static void -gsc_command_readlog (const char *argument) -{ - assert (argument); - - if (sc_strcasecmp (argument, "on") == 0) - { - frefid_t fileref; - - if (gsc_readlog_stream) - { - gsc_normal_string ("Glk read log is already on.\n"); - return; - } - - fileref = g_vm->glk_fileref_create_by_prompt (fileusage_InputRecord - | fileusage_BinaryMode, - filemode_Read, 0); - if (!fileref) - { - gsc_standout_string ("Glk read log failed.\n"); - return; - } - - if (!g_vm->glk_fileref_does_file_exist (fileref)) - { - g_vm->glk_fileref_destroy (fileref); - gsc_standout_string ("Glk read log failed.\n"); - return; - } - - gsc_readlog_stream = g_vm->glk_stream_open_file (fileref, filemode_Read, 0); - g_vm->glk_fileref_destroy (fileref); - if (!gsc_readlog_stream) - { - gsc_standout_string ("Glk read log failed.\n"); - return; - } - - gsc_normal_string ("Glk read log is now on.\n"); - } - - else if (sc_strcasecmp (argument, "off") == 0) - { - if (!gsc_readlog_stream) - { - gsc_normal_string ("Glk read log is already off.\n"); - return; - } - - g_vm->glk_stream_close (gsc_readlog_stream, nullptr); - gsc_readlog_stream = nullptr; - - gsc_normal_string ("Glk read log is now off.\n"); - } - - else if (strlen (argument) == 0) - { - gsc_normal_string ("Glk read log is "); - gsc_normal_string (gsc_readlog_stream ? "on" : "off"); - gsc_normal_string (".\n"); - } - - else - { - gsc_normal_string ("Glk read log can be "); - gsc_standout_string ("on"); - gsc_normal_string (", or "); - gsc_standout_string ("off"); - gsc_normal_string (".\n"); - } +gsc_command_readlog(const char *argument) { + assert(argument); + + if (sc_strcasecmp(argument, "on") == 0) { + frefid_t fileref; + + if (gsc_readlog_stream) { + gsc_normal_string("Glk read log is already on.\n"); + return; + } + + fileref = g_vm->glk_fileref_create_by_prompt(fileusage_InputRecord + | fileusage_BinaryMode, + filemode_Read, 0); + if (!fileref) { + gsc_standout_string("Glk read log failed.\n"); + return; + } + + if (!g_vm->glk_fileref_does_file_exist(fileref)) { + g_vm->glk_fileref_destroy(fileref); + gsc_standout_string("Glk read log failed.\n"); + return; + } + + gsc_readlog_stream = g_vm->glk_stream_open_file(fileref, filemode_Read, 0); + g_vm->glk_fileref_destroy(fileref); + if (!gsc_readlog_stream) { + gsc_standout_string("Glk read log failed.\n"); + return; + } + + gsc_normal_string("Glk read log is now on.\n"); + } + + else if (sc_strcasecmp(argument, "off") == 0) { + if (!gsc_readlog_stream) { + gsc_normal_string("Glk read log is already off.\n"); + return; + } + + g_vm->glk_stream_close(gsc_readlog_stream, nullptr); + gsc_readlog_stream = nullptr; + + gsc_normal_string("Glk read log is now off.\n"); + } + + else if (strlen(argument) == 0) { + gsc_normal_string("Glk read log is "); + gsc_normal_string(gsc_readlog_stream ? "on" : "off"); + gsc_normal_string(".\n"); + } + + else { + gsc_normal_string("Glk read log can be "); + gsc_standout_string("on"); + gsc_normal_string(", or "); + gsc_standout_string("off"); + gsc_normal_string(".\n"); + } } @@ -2022,49 +1909,42 @@ gsc_command_readlog (const char *argument) * Turn abbreviation expansions on and off. */ static void -gsc_command_abbreviations (const char *argument) -{ - assert (argument); - - if (sc_strcasecmp (argument, "on") == 0) - { - if (gsc_abbreviations_enabled) - { - gsc_normal_string ("Glk abbreviation expansions are already on.\n"); - return; - } - - gsc_abbreviations_enabled = TRUE; - gsc_normal_string ("Glk abbreviation expansions are now on.\n"); - } - - else if (sc_strcasecmp (argument, "off") == 0) - { - if (!gsc_abbreviations_enabled) - { - gsc_normal_string ("Glk abbreviation expansions are already off.\n"); - return; - } - - gsc_abbreviations_enabled = FALSE; - gsc_normal_string ("Glk abbreviation expansions are now off.\n"); - } - - else if (strlen (argument) == 0) - { - gsc_normal_string ("Glk abbreviation expansions are "); - gsc_normal_string (gsc_abbreviations_enabled ? "on" : "off"); - gsc_normal_string (".\n"); - } - - else - { - gsc_normal_string ("Glk abbreviation expansions can be "); - gsc_standout_string ("on"); - gsc_normal_string (", or "); - gsc_standout_string ("off"); - gsc_normal_string (".\n"); - } +gsc_command_abbreviations(const char *argument) { + assert(argument); + + if (sc_strcasecmp(argument, "on") == 0) { + if (gsc_abbreviations_enabled) { + gsc_normal_string("Glk abbreviation expansions are already on.\n"); + return; + } + + gsc_abbreviations_enabled = TRUE; + gsc_normal_string("Glk abbreviation expansions are now on.\n"); + } + + else if (sc_strcasecmp(argument, "off") == 0) { + if (!gsc_abbreviations_enabled) { + gsc_normal_string("Glk abbreviation expansions are already off.\n"); + return; + } + + gsc_abbreviations_enabled = FALSE; + gsc_normal_string("Glk abbreviation expansions are now off.\n"); + } + + else if (strlen(argument) == 0) { + gsc_normal_string("Glk abbreviation expansions are "); + gsc_normal_string(gsc_abbreviations_enabled ? "on" : "off"); + gsc_normal_string(".\n"); + } + + else { + gsc_normal_string("Glk abbreviation expansions can be "); + gsc_standout_string("on"); + gsc_normal_string(", or "); + gsc_standout_string("off"); + gsc_normal_string(".\n"); + } } @@ -2075,31 +1955,29 @@ gsc_command_abbreviations (const char *argument) * Print out the Glk library version number. */ static void -gsc_command_print_version_number (glui32 version) -{ - char buffer[64]; +gsc_command_print_version_number(glui32 version) { + char buffer[64]; - sprintf (buffer, "%lu.%lu.%lu", - (unsigned long) version >> 16, - (unsigned long) (version >> 8) & 0xff, - (unsigned long) version & 0xff); - gsc_normal_string (buffer); + sprintf(buffer, "%lu.%lu.%lu", + (unsigned long) version >> 16, + (unsigned long)(version >> 8) & 0xff, + (unsigned long) version & 0xff); + gsc_normal_string(buffer); } static void -gsc_command_version (const char *argument) -{ - glui32 version; - assert (argument); +gsc_command_version(const char *argument) { + glui32 version; + assert(argument); - gsc_normal_string ("This is version "); - gsc_command_print_version_number (GSC_PORT_VERSION); - gsc_normal_string (" of the Glk SCARE port.\n"); + gsc_normal_string("This is version "); + gsc_command_print_version_number(GSC_PORT_VERSION); + gsc_normal_string(" of the Glk SCARE port.\n"); - version = g_vm->glk_gestalt (gestalt_Version, 0); - gsc_normal_string ("The Glk library version is "); - gsc_command_print_version_number (version); - gsc_normal_string (".\n"); + version = g_vm->glk_gestalt(gestalt_Version, 0); + gsc_normal_string("The Glk library version is "); + gsc_command_print_version_number(version); + gsc_normal_string(".\n"); } @@ -2110,36 +1988,31 @@ gsc_command_version (const char *argument) * Commands must be on already to enter this function. */ static void -gsc_command_commands (const char *argument) -{ - assert (argument); +gsc_command_commands(const char *argument) { + assert(argument); - if (sc_strcasecmp (argument, "on") == 0) - { - gsc_normal_string ("Glk commands are already on.\n"); - } + if (sc_strcasecmp(argument, "on") == 0) { + gsc_normal_string("Glk commands are already on.\n"); + } - else if (sc_strcasecmp (argument, "off") == 0) - { - gsc_commands_enabled = FALSE; - gsc_normal_string ("Glk commands are now off.\n"); - } + else if (sc_strcasecmp(argument, "off") == 0) { + gsc_commands_enabled = FALSE; + gsc_normal_string("Glk commands are now off.\n"); + } - else if (strlen (argument) == 0) - { - gsc_normal_string ("Glk commands are "); - gsc_normal_string (gsc_commands_enabled ? "on" : "off"); - gsc_normal_string (".\n"); - } + else if (strlen(argument) == 0) { + gsc_normal_string("Glk commands are "); + gsc_normal_string(gsc_commands_enabled ? "on" : "off"); + gsc_normal_string(".\n"); + } - else - { - gsc_normal_string ("Glk commands can be "); - gsc_standout_string ("on"); - gsc_normal_string (", or "); - gsc_standout_string ("off"); - gsc_normal_string (".\n"); - } + else { + gsc_normal_string("Glk commands can be "); + gsc_standout_string("on"); + gsc_normal_string(", or "); + gsc_standout_string("off"); + gsc_normal_string(".\n"); + } } @@ -2149,59 +2022,57 @@ gsc_command_commands (const char *argument) * Print licensing terms. */ static void -gsc_command_license (const char *argument) -{ - assert (argument); +gsc_command_license(const char *argument) { + assert(argument); - gsc_normal_string ("This program is free software; you can redistribute it" - " and/or modify it under the terms of version 2 of the" - " GNU General Public License as published by the Free" - " Software Foundation.\n\n"); + gsc_normal_string("This program is free software; you can redistribute it" + " and/or modify it under the terms of version 2 of the" + " GNU General Public License as published by the Free" + " Software Foundation.\n\n"); - gsc_normal_string ("This program is distributed in the hope that it will be" - " useful, but "); - gsc_standout_string ("WITHOUT ANY WARRANTY"); - gsc_normal_string ("; without even the implied warranty of "); - gsc_standout_string ("MERCHANTABILITY"); - gsc_normal_string (" or "); - gsc_standout_string ("FITNESS FOR A PARTICULAR PURPOSE"); - gsc_normal_string (". See the GNU General Public License for more" - " details.\n\n"); + gsc_normal_string("This program is distributed in the hope that it will be" + " useful, but "); + gsc_standout_string("WITHOUT ANY WARRANTY"); + gsc_normal_string("; without even the implied warranty of "); + gsc_standout_string("MERCHANTABILITY"); + gsc_normal_string(" or "); + gsc_standout_string("FITNESS FOR A PARTICULAR PURPOSE"); + gsc_normal_string(". See the GNU General Public License for more" + " details.\n\n"); - gsc_normal_string ("You should have received a copy of the GNU General" - " Public License along with this program; if not, write" - " to the Free Software Foundation, Inc., 51 Franklin" - " Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"); + gsc_normal_string("You should have received a copy of the GNU General" + " Public License along with this program; if not, write" + " to the Free Software Foundation, Inc., 51 Franklin" + " Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"); - gsc_normal_string ("Please report any bugs, omissions, or misfeatures to "); - gsc_standout_string ("simon_baldwin@yahoo.com"); - gsc_normal_string (".\n"); + gsc_normal_string("Please report any bugs, omissions, or misfeatures to "); + gsc_standout_string("simon_baldwin@yahoo.com"); + gsc_normal_string(".\n"); } /* Glk subcommands and handler functions. */ -typedef const struct -{ - const char * const command; /* Glk subcommand. */ - void (* const handler) (const char *argument); /* Subcommand handler. */ - const int takes_argument; /* Argument flag. */ +typedef const struct { + const char *const command; /* Glk subcommand. */ + void (* const handler)(const char *argument); /* Subcommand handler. */ + const int takes_argument; /* Argument flag. */ } gsc_command_t; typedef gsc_command_t *gsc_commandref_t; -static void gsc_command_summary (const char *argument); -static void gsc_command_help (const char *argument); +static void gsc_command_summary(const char *argument); +static void gsc_command_help(const char *argument); static gsc_command_t GSC_COMMAND_TABLE[] = { - {"summary", gsc_command_summary, FALSE}, - {"script", gsc_command_script, TRUE}, - {"inputlog", gsc_command_inputlog, TRUE}, - {"readlog", gsc_command_readlog, TRUE}, - {"abbreviations", gsc_command_abbreviations, TRUE}, - {"version", gsc_command_version, FALSE}, - {"commands", gsc_command_commands, TRUE}, - {"license", gsc_command_license, FALSE}, - {"help", gsc_command_help, TRUE}, - {nullptr, nullptr, FALSE} + {"summary", gsc_command_summary, FALSE}, + {"script", gsc_command_script, TRUE}, + {"inputlog", gsc_command_inputlog, TRUE}, + {"readlog", gsc_command_readlog, TRUE}, + {"abbreviations", gsc_command_abbreviations, TRUE}, + {"version", gsc_command_version, FALSE}, + {"commands", gsc_command_commands, TRUE}, + {"license", gsc_command_license, FALSE}, + {"help", gsc_command_help, TRUE}, + {nullptr, nullptr, FALSE} }; @@ -2211,24 +2082,22 @@ static gsc_command_t GSC_COMMAND_TABLE[] = { * Report all current Glk settings. */ static void -gsc_command_summary (const char *argument) -{ - gsc_commandref_t entry; - assert (argument); +gsc_command_summary(const char *argument) { + gsc_commandref_t entry; + assert(argument); - /* - * Call handlers that have status to report with an empty argument, - * prompting each to print its current setting. - */ - for (entry = GSC_COMMAND_TABLE; entry->command; entry++) - { - if (entry->handler == gsc_command_summary - || entry->handler == gsc_command_license - || entry->handler == gsc_command_help) - continue; + /* + * Call handlers that have status to report with an empty argument, + * prompting each to print its current setting. + */ + for (entry = GSC_COMMAND_TABLE; entry->command; entry++) { + if (entry->handler == gsc_command_summary + || entry->handler == gsc_command_license + || entry->handler == gsc_command_help) + continue; - entry->handler (""); - } + entry->handler(""); + } } @@ -2238,139 +2107,124 @@ gsc_command_summary (const char *argument) * Document the available Glk commands. */ static void -gsc_command_help (const char *command) -{ - gsc_commandref_t entry, matched; - assert (command); - - if (strlen (command) == 0) - { - gsc_normal_string ("Glk commands are"); - for (entry = GSC_COMMAND_TABLE; entry->command; entry++) - { - gsc_commandref_t next; - - next = entry + 1; - gsc_normal_string (next->command ? " " : " and "); - gsc_standout_string (entry->command); - gsc_normal_string (next->command ? "," : ".\n\n"); - } - - gsc_normal_string ("Glk commands may be abbreviated, as long as" - " the abbreviation is unambiguous. Use "); - gsc_standout_string ("glk help"); - gsc_normal_string (" followed by a Glk command name for help on that" - " command.\n"); - return; - } - - matched = nullptr; - for (entry = GSC_COMMAND_TABLE; entry->command; entry++) - { - if (sc_strncasecmp (command, entry->command, strlen (command)) == 0) - { - if (matched) - { - gsc_normal_string ("The Glk command "); - gsc_standout_string (command); - gsc_normal_string (" is ambiguous. Try "); - gsc_standout_string ("glk help"); - gsc_normal_string (" for more information.\n"); - return; - } - matched = entry; - } - } - if (!matched) - { - gsc_normal_string ("The Glk command "); - gsc_standout_string (command); - gsc_normal_string (" is not valid. Try "); - gsc_standout_string ("glk help"); - gsc_normal_string (" for more information.\n"); - return; - } - - if (matched->handler == gsc_command_summary) - { - gsc_normal_string ("Prints a summary of all the current Glk SCARE" - " settings.\n"); - } - - else if (matched->handler == gsc_command_script) - { - gsc_normal_string ("Logs the game's output to a file.\n\nUse "); - gsc_standout_string ("glk script on"); - gsc_normal_string (" to begin logging game output, and "); - gsc_standout_string ("glk script off"); - gsc_normal_string (" to end it. Glk SCARE will ask you for a file" - " when you turn scripts on.\n"); - } - - else if (matched->handler == gsc_command_inputlog) - { - gsc_normal_string ("Records the commands you type into a game.\n\nUse "); - gsc_standout_string ("glk inputlog on"); - gsc_normal_string (", to begin recording your commands, and "); - gsc_standout_string ("glk inputlog off"); - gsc_normal_string (" to turn off input logs. You can play back" - " recorded commands into a game with the "); - gsc_standout_string ("glk readlog"); - gsc_normal_string (" command.\n"); - } - - else if (matched->handler == gsc_command_readlog) - { - gsc_normal_string ("Plays back commands recorded with "); - gsc_standout_string ("glk inputlog on"); - gsc_normal_string (".\n\nUse "); - gsc_standout_string ("glk readlog on"); - gsc_normal_string (". Command play back stops at the end of the" - " file. You can also play back commands from a" - " text file created using any standard editor.\n"); - } - - else if (matched->handler == gsc_command_abbreviations) - { - gsc_normal_string ("Controls abbreviation expansion.\n\nGlk SCARE" - " automatically expands several standard single" - " letter abbreviations for you; for example, \"x\"" - " becomes \"examine\". Use "); - gsc_standout_string ("glk abbreviations on"); - gsc_normal_string (" to turn this feature on, and "); - gsc_standout_string ("glk abbreviations off"); - gsc_normal_string (" to turn it off. While the feature is on, you" - " can bypass abbreviation expansion for an" - " individual game command by prefixing it with a" - " single quote.\n"); - } - - else if (matched->handler == gsc_command_version) - { - gsc_normal_string ("Prints the version numbers of the Glk library" - " and the Glk SCARE port.\n"); - } - - else if (matched->handler == gsc_command_commands) - { - gsc_normal_string ("Turn off Glk commands.\n\nUse "); - gsc_standout_string ("glk commands off"); - gsc_normal_string (" to disable all Glk commands, including this one." - " Once turned off, there is no way to turn Glk" - " commands back on while inside the game.\n"); - } - - else if (matched->handler == gsc_command_license) - { - gsc_normal_string ("Prints Glk SCARE's software license.\n"); - } - - else if (matched->handler == gsc_command_help) - gsc_command_help (""); - - else - gsc_normal_string ("There is no help available on that Glk command." - " Sorry.\n"); +gsc_command_help(const char *command) { + gsc_commandref_t entry, matched; + assert(command); + + if (strlen(command) == 0) { + gsc_normal_string("Glk commands are"); + for (entry = GSC_COMMAND_TABLE; entry->command; entry++) { + gsc_commandref_t next; + + next = entry + 1; + gsc_normal_string(next->command ? " " : " and "); + gsc_standout_string(entry->command); + gsc_normal_string(next->command ? "," : ".\n\n"); + } + + gsc_normal_string("Glk commands may be abbreviated, as long as" + " the abbreviation is unambiguous. Use "); + gsc_standout_string("glk help"); + gsc_normal_string(" followed by a Glk command name for help on that" + " command.\n"); + return; + } + + matched = nullptr; + for (entry = GSC_COMMAND_TABLE; entry->command; entry++) { + if (sc_strncasecmp(command, entry->command, strlen(command)) == 0) { + if (matched) { + gsc_normal_string("The Glk command "); + gsc_standout_string(command); + gsc_normal_string(" is ambiguous. Try "); + gsc_standout_string("glk help"); + gsc_normal_string(" for more information.\n"); + return; + } + matched = entry; + } + } + if (!matched) { + gsc_normal_string("The Glk command "); + gsc_standout_string(command); + gsc_normal_string(" is not valid. Try "); + gsc_standout_string("glk help"); + gsc_normal_string(" for more information.\n"); + return; + } + + if (matched->handler == gsc_command_summary) { + gsc_normal_string("Prints a summary of all the current Glk SCARE" + " settings.\n"); + } + + else if (matched->handler == gsc_command_script) { + gsc_normal_string("Logs the game's output to a file.\n\nUse "); + gsc_standout_string("glk script on"); + gsc_normal_string(" to begin logging game output, and "); + gsc_standout_string("glk script off"); + gsc_normal_string(" to end it. Glk SCARE will ask you for a file" + " when you turn scripts on.\n"); + } + + else if (matched->handler == gsc_command_inputlog) { + gsc_normal_string("Records the commands you type into a game.\n\nUse "); + gsc_standout_string("glk inputlog on"); + gsc_normal_string(", to begin recording your commands, and "); + gsc_standout_string("glk inputlog off"); + gsc_normal_string(" to turn off input logs. You can play back" + " recorded commands into a game with the "); + gsc_standout_string("glk readlog"); + gsc_normal_string(" command.\n"); + } + + else if (matched->handler == gsc_command_readlog) { + gsc_normal_string("Plays back commands recorded with "); + gsc_standout_string("glk inputlog on"); + gsc_normal_string(".\n\nUse "); + gsc_standout_string("glk readlog on"); + gsc_normal_string(". Command play back stops at the end of the" + " file. You can also play back commands from a" + " text file created using any standard editor.\n"); + } + + else if (matched->handler == gsc_command_abbreviations) { + gsc_normal_string("Controls abbreviation expansion.\n\nGlk SCARE" + " automatically expands several standard single" + " letter abbreviations for you; for example, \"x\"" + " becomes \"examine\". Use "); + gsc_standout_string("glk abbreviations on"); + gsc_normal_string(" to turn this feature on, and "); + gsc_standout_string("glk abbreviations off"); + gsc_normal_string(" to turn it off. While the feature is on, you" + " can bypass abbreviation expansion for an" + " individual game command by prefixing it with a" + " single quote.\n"); + } + + else if (matched->handler == gsc_command_version) { + gsc_normal_string("Prints the version numbers of the Glk library" + " and the Glk SCARE port.\n"); + } + + else if (matched->handler == gsc_command_commands) { + gsc_normal_string("Turn off Glk commands.\n\nUse "); + gsc_standout_string("glk commands off"); + gsc_normal_string(" to disable all Glk commands, including this one." + " Once turned off, there is no way to turn Glk" + " commands back on while inside the game.\n"); + } + + else if (matched->handler == gsc_command_license) { + gsc_normal_string("Prints Glk SCARE's software license.\n"); + } + + else if (matched->handler == gsc_command_help) + gsc_command_help(""); + + else + gsc_normal_string("There is no help available on that Glk command." + " Sorry.\n"); } @@ -2381,103 +2235,94 @@ gsc_command_help (const char *command) * Glk port command, handle it and return TRUE, otherwise return FALSE. */ static int -gsc_command_escape (const char *string) -{ - int posn; - char *string_copy, *command, *argument; - assert (string); - - /* - * Return FALSE if the string doesn't begin with the Glk command escape - * introducer. - */ - posn = strspn (string, "\t "); - if (sc_strncasecmp (string + posn, "glk", strlen ("glk")) != 0) - return FALSE; - - /* Take a copy of the string, without any leading space or introducer. */ - string_copy = (char *)gsc_malloc (strlen (string + posn) + 1 - strlen ("glk")); - strcpy (string_copy, string + posn + strlen ("glk")); - - /* - * Find the subcommand; the first word in the string copy. Find its end, - * and ensure it terminates with a NUL. - */ - posn = strspn (string_copy, "\t "); - command = string_copy + posn; - posn += strcspn (string_copy + posn, "\t "); - if (string_copy[posn] != '\0') - string_copy[posn++] = '\0'; - - /* - * Now find any argument data for the command, ensuring it too terminates - * with a NUL. - */ - posn += strspn (string_copy + posn, "\t "); - argument = string_copy + posn; - posn += strcspn (string_copy + posn, "\t "); - string_copy[posn] = '\0'; - - /* - * Try to handle the command and argument as a Glk subcommand. If it - * doesn't run unambiguously, print command usage. Treat an empty command - * as "help". - */ - if (strlen (command) > 0) - { - gsc_commandref_t entry, matched; - int matches; - - /* - * Search for the first unambiguous table command string matching - * the command passed in. - */ - matches = 0; - matched = nullptr; - for (entry = GSC_COMMAND_TABLE; entry->command; entry++) - { - if (sc_strncasecmp (command, entry->command, strlen (command)) == 0) - { - matches++; - matched = entry; - } - } - - /* If the match was unambiguous, call the command handler. */ - if (matches == 1) - { - gsc_normal_char ('\n'); - matched->handler (argument); - - if (!matched->takes_argument && strlen (argument) > 0) - { - gsc_normal_string ("[The "); - gsc_standout_string (matched->command); - gsc_normal_string (" command ignores arguments.]\n"); - } - } - - /* No match, or the command was ambiguous. */ - else - { - gsc_normal_string ("\nThe Glk command "); - gsc_standout_string (command); - gsc_normal_string (" is "); - gsc_normal_string (matches == 0 ? "not valid" : "ambiguous"); - gsc_normal_string (". Try "); - gsc_standout_string ("glk help"); - gsc_normal_string (" for more information.\n"); - } - } - else - { - gsc_normal_char ('\n'); - gsc_command_help (""); - } - - /* The string contained a Glk command; return TRUE. */ - free (string_copy); - return TRUE; +gsc_command_escape(const char *string) { + int posn; + char *string_copy, *command, *argument; + assert(string); + + /* + * Return FALSE if the string doesn't begin with the Glk command escape + * introducer. + */ + posn = strspn(string, "\t "); + if (sc_strncasecmp(string + posn, "glk", strlen("glk")) != 0) + return FALSE; + + /* Take a copy of the string, without any leading space or introducer. */ + string_copy = (char *)gsc_malloc(strlen(string + posn) + 1 - strlen("glk")); + strcpy(string_copy, string + posn + strlen("glk")); + + /* + * Find the subcommand; the first word in the string copy. Find its end, + * and ensure it terminates with a NUL. + */ + posn = strspn(string_copy, "\t "); + command = string_copy + posn; + posn += strcspn(string_copy + posn, "\t "); + if (string_copy[posn] != '\0') + string_copy[posn++] = '\0'; + + /* + * Now find any argument data for the command, ensuring it too terminates + * with a NUL. + */ + posn += strspn(string_copy + posn, "\t "); + argument = string_copy + posn; + posn += strcspn(string_copy + posn, "\t "); + string_copy[posn] = '\0'; + + /* + * Try to handle the command and argument as a Glk subcommand. If it + * doesn't run unambiguously, print command usage. Treat an empty command + * as "help". + */ + if (strlen(command) > 0) { + gsc_commandref_t entry, matched; + int matches; + + /* + * Search for the first unambiguous table command string matching + * the command passed in. + */ + matches = 0; + matched = nullptr; + for (entry = GSC_COMMAND_TABLE; entry->command; entry++) { + if (sc_strncasecmp(command, entry->command, strlen(command)) == 0) { + matches++; + matched = entry; + } + } + + /* If the match was unambiguous, call the command handler. */ + if (matches == 1) { + gsc_normal_char('\n'); + matched->handler(argument); + + if (!matched->takes_argument && strlen(argument) > 0) { + gsc_normal_string("[The "); + gsc_standout_string(matched->command); + gsc_normal_string(" command ignores arguments.]\n"); + } + } + + /* No match, or the command was ambiguous. */ + else { + gsc_normal_string("\nThe Glk command "); + gsc_standout_string(command); + gsc_normal_string(" is "); + gsc_normal_string(matches == 0 ? "not valid" : "ambiguous"); + gsc_normal_string(". Try "); + gsc_standout_string("glk help"); + gsc_normal_string(" for more information.\n"); + } + } else { + gsc_normal_char('\n'); + gsc_command_help(""); + } + + /* The string contained a Glk command; return TRUE. */ + free(string_copy); + return TRUE; } @@ -2490,19 +2335,18 @@ static const char GSC_QUOTED_INPUT = '\''; /* Table of single-character command abbreviations. */ -typedef const struct -{ - const char abbreviation; /* Abbreviation character. */ - const char *const expansion; /* Expansion string. */ +typedef const struct { + const char abbreviation; /* Abbreviation character. */ + const char *const expansion; /* Expansion string. */ } gsc_abbreviation_t; typedef gsc_abbreviation_t *gsc_abbreviationref_t; static gsc_abbreviation_t GSC_ABBREVIATIONS[] = { - {'c', "close"}, {'g', "again"}, {'i', "inventory"}, - {'k', "attack"}, {'l', "look"}, {'p', "open"}, - {'q', "quit"}, {'r', "drop"}, {'t', "take"}, - {'x', "examine"}, {'y', "yes"}, {'z', "wait"}, - {'\0', nullptr} + {'c', "close"}, {'g', "again"}, {'i', "inventory"}, + {'k', "attack"}, {'l', "look"}, {'p', "open"}, + {'q', "quit"}, {'r', "drop"}, {'t', "take"}, + {'x', "examine"}, {'y', "yes"}, {'z', "wait"}, + {'\0', nullptr} }; @@ -2513,49 +2357,45 @@ static gsc_abbreviation_t GSC_ABBREVIATIONS[] = { * game systems. */ static void -gsc_expand_abbreviations (char *buffer, int size) -{ - char *command, abbreviation; - const char *expansion; - gsc_abbreviationref_t entry; - assert (buffer); - - /* Ignore anything that isn't a single letter command. */ - command = buffer + strspn (buffer, "\t "); - if (!(strlen (command) == 1 - || (strlen (command) > 1 && Common::isSpace(command[1])))) - return; - - /* Scan the abbreviations table for a match. */ - abbreviation = g_vm->glk_char_to_lower ((unsigned char) command[0]); - expansion = nullptr; - for (entry = GSC_ABBREVIATIONS; entry->expansion; entry++) - { - if (entry->abbreviation == abbreviation) - { - expansion = entry->expansion; - break; - } - } - - /* - * If a match found, check for a fit, then replace the character with the - * expansion string. - */ - if (expansion) - { - if (strlen (buffer) + strlen (expansion) - 1 >= (unsigned int) size) - return; - - memmove (command + strlen (expansion) - 1, command, strlen (command) + 1); - memcpy (command, expansion, strlen (expansion)); - - gsc_standout_string ("["); - gsc_standout_char (abbreviation); - gsc_standout_string (" -> "); - gsc_standout_string (expansion); - gsc_standout_string ("]\n"); - } +gsc_expand_abbreviations(char *buffer, int size) { + char *command, abbreviation; + const char *expansion; + gsc_abbreviationref_t entry; + assert(buffer); + + /* Ignore anything that isn't a single letter command. */ + command = buffer + strspn(buffer, "\t "); + if (!(strlen(command) == 1 + || (strlen(command) > 1 && Common::isSpace(command[1])))) + return; + + /* Scan the abbreviations table for a match. */ + abbreviation = g_vm->glk_char_to_lower((unsigned char) command[0]); + expansion = nullptr; + for (entry = GSC_ABBREVIATIONS; entry->expansion; entry++) { + if (entry->abbreviation == abbreviation) { + expansion = entry->expansion; + break; + } + } + + /* + * If a match found, check for a fit, then replace the character with the + * expansion string. + */ + if (expansion) { + if (strlen(buffer) + strlen(expansion) - 1 >= (unsigned int) size) + return; + + memmove(command + strlen(expansion) - 1, command, strlen(command) + 1); + memcpy(command, expansion, strlen(expansion)); + + gsc_standout_string("["); + gsc_standout_char(abbreviation); + gsc_standout_string(" -> "); + gsc_standout_string(expansion); + gsc_standout_string("]\n"); + } } @@ -2565,123 +2405,111 @@ gsc_expand_abbreviations (char *buffer, int size) * Read and return a line of player input. */ sc_bool -os_read_line (sc_char *buffer, sc_int length) -{ - sc_int characters; - assert (buffer && length > 0); - - /* If a help request is pending, provide a user hint. */ - gsc_output_provide_help_hint (); - - /* - * Ensure normal style, update the status line, and issue an input prompt. - */ - gsc_reset_glk_style (); - gsc_status_notify (); - g_vm->glk_put_string (">"); - - /* - * If we have an input log to read from, use that until it is exhausted. - * On end of file, close the stream and resume input from line requests. - */ - if (gsc_readlog_stream) - { - glui32 chars; - - /* Get the next line from the log stream. */ - chars = g_vm->glk_get_line_stream (gsc_readlog_stream, buffer, length); - if (chars > 0) - { - /* Echo the line just read in input style. */ - g_vm->glk_set_style (style_Input); - gsc_put_buffer (buffer, chars); - g_vm->glk_set_style (style_Normal); - - /* Return this line as player input. */ - return TRUE; - } - - /* - * We're at the end of the log stream. Close it, and then continue - * on to request a line from Glk. - */ - g_vm->glk_stream_close (gsc_readlog_stream, nullptr); - gsc_readlog_stream = nullptr; - } - - /* - * No input log being read, or we just hit the end of file on one. Revert - * to normal line input; start by getting a new line from Glk. - */ - characters = gsc_read_line (buffer, length - 1); - assert (characters <= length); - buffer[characters] = '\0'; - - /* - * If neither abbreviations nor local commands are enabled, use the data - * read above without further massaging. - */ - if (gsc_abbreviations_enabled || gsc_commands_enabled) - { - char *command; - - /* - * If the first non-space input character is a quote, bypass all - * abbreviation expansion and local command recognition, and use the - * unadulterated input, less introductory quote. - */ - command = buffer + strspn (buffer, "\t "); - if (command[0] == GSC_QUOTED_INPUT) - { - /* Delete the quote with memmove(). */ - memmove (command, command + 1, strlen (command)); - } - else - { - /* Check for, and expand, and abbreviated commands. */ - if (gsc_abbreviations_enabled) - gsc_expand_abbreviations (buffer, length); - - /* - * Check for standalone "help", then for Glk port special commands; - * suppress the interpreter's use of this input for Glk commands by - * returning FALSE. - */ - if (gsc_commands_enabled) - { - int posn; - - posn = strspn (buffer, "\t "); - if (sc_strncasecmp (buffer + posn, "help", strlen ("help"))== 0) - { - if (strspn (buffer + posn + strlen ("help"), "\t ") - == strlen (buffer + posn + strlen ("help"))) - { - gsc_output_register_help_request (); - } - } - - if (gsc_command_escape (buffer)) - { - gsc_output_silence_help_hints (); - return FALSE; - } - } - } - } - - /* - * If there is an input log active, log this input string to it. Note that - * by logging here we get any abbreviation expansions but we won't log glk - * special commands, nor any input read from a current open input log. - */ - if (gsc_inputlog_stream) - { - g_vm->glk_put_string_stream (gsc_inputlog_stream, buffer); - g_vm->glk_put_char_stream (gsc_inputlog_stream, '\n'); - } - - return TRUE; +os_read_line(sc_char *buffer, sc_int length) { + sc_int characters; + assert(buffer && length > 0); + + /* If a help request is pending, provide a user hint. */ + gsc_output_provide_help_hint(); + + /* + * Ensure normal style, update the status line, and issue an input prompt. + */ + gsc_reset_glk_style(); + gsc_status_notify(); + g_vm->glk_put_string(">"); + + /* + * If we have an input log to read from, use that until it is exhausted. + * On end of file, close the stream and resume input from line requests. + */ + if (gsc_readlog_stream) { + glui32 chars; + + /* Get the next line from the log stream. */ + chars = g_vm->glk_get_line_stream(gsc_readlog_stream, buffer, length); + if (chars > 0) { + /* Echo the line just read in input style. */ + g_vm->glk_set_style(style_Input); + gsc_put_buffer(buffer, chars); + g_vm->glk_set_style(style_Normal); + + /* Return this line as player input. */ + return TRUE; + } + + /* + * We're at the end of the log stream. Close it, and then continue + * on to request a line from Glk. + */ + g_vm->glk_stream_close(gsc_readlog_stream, nullptr); + gsc_readlog_stream = nullptr; + } + + /* + * No input log being read, or we just hit the end of file on one. Revert + * to normal line input; start by getting a new line from Glk. + */ + characters = gsc_read_line(buffer, length - 1); + assert(characters <= length); + buffer[characters] = '\0'; + + /* + * If neither abbreviations nor local commands are enabled, use the data + * read above without further massaging. + */ + if (gsc_abbreviations_enabled || gsc_commands_enabled) { + char *command; + + /* + * If the first non-space input character is a quote, bypass all + * abbreviation expansion and local command recognition, and use the + * unadulterated input, less introductory quote. + */ + command = buffer + strspn(buffer, "\t "); + if (command[0] == GSC_QUOTED_INPUT) { + /* Delete the quote with memmove(). */ + memmove(command, command + 1, strlen(command)); + } else { + /* Check for, and expand, and abbreviated commands. */ + if (gsc_abbreviations_enabled) + gsc_expand_abbreviations(buffer, length); + + /* + * Check for standalone "help", then for Glk port special commands; + * suppress the interpreter's use of this input for Glk commands by + * returning FALSE. + */ + if (gsc_commands_enabled) { + int posn; + + posn = strspn(buffer, "\t "); + if (sc_strncasecmp(buffer + posn, "help", strlen("help")) == 0) { + if (strspn(buffer + posn + strlen("help"), "\t ") + == strlen(buffer + posn + strlen("help"))) { + gsc_output_register_help_request(); + } + } + + if (gsc_command_escape(buffer)) { + gsc_output_silence_help_hints(); + return FALSE; + } + } + } + } + + /* + * If there is an input log active, log this input string to it. Note that + * by logging here we get any abbreviation expansions but we won't log glk + * special commands, nor any input read from a current open input log. + */ + if (gsc_inputlog_stream) { + g_vm->glk_put_string_stream(gsc_inputlog_stream, buffer); + g_vm->glk_put_char_stream(gsc_inputlog_stream, '\n'); + } + + return TRUE; } @@ -2693,12 +2521,11 @@ os_read_line (sc_char *buffer, sc_int length) * prompt. */ sc_bool -os_read_line_debug (sc_char *buffer, sc_int length) -{ - gsc_output_silence_help_hints (); - gsc_reset_glk_style (); - g_vm->glk_put_string ("[SCARE debug]"); - return os_read_line (buffer, length); +os_read_line_debug(sc_char *buffer, sc_int length) { + gsc_output_silence_help_hints(); + gsc_reset_glk_style(); + g_vm->glk_put_string("[SCARE debug]"); + return os_read_line(buffer, length); } @@ -2708,85 +2535,78 @@ os_read_line_debug (sc_char *buffer, sc_int length) * Confirm a game action with a yes/no prompt. */ sc_bool -os_confirm (sc_int type) -{ - sc_char response; - - /* - * Always allow game saves and hint display, and if we're reading from an - * input log, allow everything no matter what, on the assumption that the - * user knows what they are doing. - */ - if (gsc_readlog_stream - || type == SC_CONF_SAVE || type == SC_CONF_VIEW_HINTS) - return TRUE; - - /* Ensure back to normal style, and update status. */ - gsc_reset_glk_style (); - gsc_status_notify (); - - /* Prompt for the confirmation, based on the type. */ - if (type == GSC_CONF_SUBTLE_HINT) - g_vm->glk_put_string ("View the subtle hint for this topic"); - else if (type == GSC_CONF_UNSUBTLE_HINT) - g_vm->glk_put_string ("View the unsubtle hint for this topic"); - else if (type == GSC_CONF_CONTINUE_HINTS) - g_vm->glk_put_string ("Continue with hints"); - else - { - g_vm->glk_put_string ("Do you really want to "); - switch (type) - { - case SC_CONF_QUIT: - g_vm->glk_put_string ("quit"); - break; - case SC_CONF_RESTART: - g_vm->glk_put_string ("restart"); - break; - case SC_CONF_SAVE: - g_vm->glk_put_string ("save"); - break; - case SC_CONF_RESTORE: - g_vm->glk_put_string ("restore"); - break; - case SC_CONF_VIEW_HINTS: - g_vm->glk_put_string ("view hints"); - break; - default: - g_vm->glk_put_string ("do that"); - break; - } - } - g_vm->glk_put_string ("? "); - - /* Loop until 'yes' or 'no' returned. */ - do - { - event_t event; - - /* Wait for a standard key, ignoring Glk special keys. */ - do - { - g_vm->glk_request_char_event (gsc_main_window); - gsc_event_wait (evtype_CharInput, &event); - } - while (event.val1 > UCHAR_MAX); - response = g_vm->glk_char_to_upper (event.val1); - } - while (response != 'Y' && response != 'N'); - - /* Echo the confirmation response, and a new line. */ - g_vm->glk_set_style (style_Input); - g_vm->glk_put_string (response == 'Y' ? "Yes" : "No"); - g_vm->glk_set_style (style_Normal); - g_vm->glk_put_char ('\n'); - - /* Use a short delay on restarts, if confirmed. */ - if (type == SC_CONF_RESTART && response == 'Y') - gsc_short_delay (); - - /* Return TRUE if 'Y' was entered. */ - return (response == 'Y'); +os_confirm(sc_int type) { + sc_char response; + + /* + * Always allow game saves and hint display, and if we're reading from an + * input log, allow everything no matter what, on the assumption that the + * user knows what they are doing. + */ + if (gsc_readlog_stream + || type == SC_CONF_SAVE || type == SC_CONF_VIEW_HINTS) + return TRUE; + + /* Ensure back to normal style, and update status. */ + gsc_reset_glk_style(); + gsc_status_notify(); + + /* Prompt for the confirmation, based on the type. */ + if (type == GSC_CONF_SUBTLE_HINT) + g_vm->glk_put_string("View the subtle hint for this topic"); + else if (type == GSC_CONF_UNSUBTLE_HINT) + g_vm->glk_put_string("View the unsubtle hint for this topic"); + else if (type == GSC_CONF_CONTINUE_HINTS) + g_vm->glk_put_string("Continue with hints"); + else { + g_vm->glk_put_string("Do you really want to "); + switch (type) { + case SC_CONF_QUIT: + g_vm->glk_put_string("quit"); + break; + case SC_CONF_RESTART: + g_vm->glk_put_string("restart"); + break; + case SC_CONF_SAVE: + g_vm->glk_put_string("save"); + break; + case SC_CONF_RESTORE: + g_vm->glk_put_string("restore"); + break; + case SC_CONF_VIEW_HINTS: + g_vm->glk_put_string("view hints"); + break; + default: + g_vm->glk_put_string("do that"); + break; + } + } + g_vm->glk_put_string("? "); + + /* Loop until 'yes' or 'no' returned. */ + do { + event_t event; + + /* Wait for a standard key, ignoring Glk special keys. */ + do { + g_vm->glk_request_char_event(gsc_main_window); + gsc_event_wait(evtype_CharInput, &event); + } while (event.val1 > UCHAR_MAX); + response = g_vm->glk_char_to_upper(event.val1); + } while (response != 'Y' && response != 'N'); + + /* Echo the confirmation response, and a new line. */ + g_vm->glk_set_style(style_Input); + g_vm->glk_put_string(response == 'Y' ? "Yes" : "No"); + g_vm->glk_set_style(style_Normal); + g_vm->glk_put_char('\n'); + + /* Use a short delay on restarts, if confirmed. */ + if (type == SC_CONF_RESTART && response == 'Y') + gsc_short_delay(); + + /* Return TRUE if 'Y' was entered. */ + return (response == 'Y'); } @@ -2806,23 +2626,20 @@ static const glui32 GSC_DELAY_TIMEOUTS_COUNT = 10; * immediate, and abrupt, restart. */ static void -gsc_short_delay() -{ - /* Ignore the call if the Glk doesn't have timers. */ - if (g_vm->glk_gestalt (gestalt_Timer, 0)) - { - glui32 timeout; - - /* Timeout in small chunks to minimize Glk jitter. */ - g_vm->glk_request_timer_events (GSC_DELAY_TIMEOUT); - for (timeout = 0; timeout < GSC_DELAY_TIMEOUTS_COUNT; timeout++) - { - event_t event; +gsc_short_delay() { + /* Ignore the call if the Glk doesn't have timers. */ + if (g_vm->glk_gestalt(gestalt_Timer, 0)) { + glui32 timeout; + + /* Timeout in small chunks to minimize Glk jitter. */ + g_vm->glk_request_timer_events(GSC_DELAY_TIMEOUT); + for (timeout = 0; timeout < GSC_DELAY_TIMEOUTS_COUNT; timeout++) { + event_t event; - gsc_event_wait (evtype_Timer, &event); - } - g_vm->glk_request_timer_events (0); - } + gsc_event_wait(evtype_Timer, &event); + } + g_vm->glk_request_timer_events(0); + } } @@ -2834,36 +2651,31 @@ gsc_short_delay() * Return the event of that type. */ static void -gsc_event_wait_2 (glui32 wait_type_1, glui32 wait_type_2, event_t * event) -{ - assert (event); - - do - { - g_vm->glk_select (event); - if (g_vm->shouldQuit()) { - g_vm->glk_cancel_line_event(gsc_main_window, event); - return; - } - - switch (event->type) - { - case evtype_Arrange: - case evtype_Redraw: - /* Refresh any sensitive windows on size events. */ - gsc_status_redraw (); - break; - } - } - while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2)); +gsc_event_wait_2(glui32 wait_type_1, glui32 wait_type_2, event_t *event) { + assert(event); + + do { + g_vm->glk_select(event); + if (g_vm->shouldQuit()) { + g_vm->glk_cancel_line_event(gsc_main_window, event); + return; + } + + switch (event->type) { + case evtype_Arrange: + case evtype_Redraw: + /* Refresh any sensitive windows on size events. */ + gsc_status_redraw(); + break; + } + } while (!(event->type == (EvType)wait_type_1 || event->type == (EvType)wait_type_2)); } static void -gsc_event_wait (glui32 wait_type, event_t * event) -{ - assert (event); +gsc_event_wait(glui32 wait_type, event_t *event) { + assert(event); - gsc_event_wait_2 (wait_type, evtype_None, event); + gsc_event_wait_2(wait_type, evtype_None, event); } @@ -2877,28 +2689,27 @@ gsc_event_wait (glui32 wait_type, event_t * event) * Open a file for save or restore, and return a Glk stream for the opened * file. */ -void *os_open_file (sc_bool is_save) { - glui32 usage, fmode; - frefid_t fileref; - strid_t stream; +void *os_open_file(sc_bool is_save) { + glui32 usage, fmode; + frefid_t fileref; + strid_t stream; - usage = fileusage_SavedGame | fileusage_BinaryMode; - fmode = is_save ? filemode_Write : filemode_Read; + usage = fileusage_SavedGame | fileusage_BinaryMode; + fmode = is_save ? filemode_Write : filemode_Read; - fileref = g_vm->glk_fileref_create_by_prompt(usage, (FileMode)fmode, 0); - if (!fileref) - return nullptr; + fileref = g_vm->glk_fileref_create_by_prompt(usage, (FileMode)fmode, 0); + if (!fileref) + return nullptr; - if (!is_save && !g_vm->glk_fileref_does_file_exist (fileref)) - { - g_vm->glk_fileref_destroy (fileref); - return nullptr; - } + if (!is_save && !g_vm->glk_fileref_does_file_exist(fileref)) { + g_vm->glk_fileref_destroy(fileref); + return nullptr; + } - stream = g_vm->glk_stream_open_file (fileref, (FileMode)fmode, 0); - g_vm->glk_fileref_destroy (fileref); + stream = g_vm->glk_stream_open_file(fileref, (FileMode)fmode, 0); + g_vm->glk_fileref_destroy(fileref); - return stream; + return stream; } @@ -2909,21 +2720,19 @@ void *os_open_file (sc_bool is_save) { * Write/read the given buffered data to/from the open Glk stream. */ void -os_write_file (void *opaque, const sc_byte *buffer, sc_int length) -{ - strid_t stream = (strid_t) opaque; - assert (opaque && buffer); +os_write_file(void *opaque, const sc_byte *buffer, sc_int length) { + strid_t stream = (strid_t) opaque; + assert(opaque && buffer); - g_vm->glk_put_buffer_stream (stream, (char *) buffer, length); + g_vm->glk_put_buffer_stream(stream, (char *) buffer, length); } sc_int -os_read_file (void *opaque, sc_byte *buffer, sc_int length) -{ - strid_t stream = (strid_t) opaque; - assert (opaque && buffer); +os_read_file(void *opaque, sc_byte *buffer, sc_int length) { + strid_t stream = (strid_t) opaque; + assert(opaque && buffer); - return g_vm->glk_get_buffer_stream (stream, (char *) buffer, length); + return g_vm->glk_get_buffer_stream(stream, (char *) buffer, length); } @@ -2933,12 +2742,11 @@ os_read_file (void *opaque, sc_byte *buffer, sc_int length) * Close the opened Glk stream. */ void -os_close_file (void *opaque) -{ - strid_t stream = (strid_t) opaque; - assert (opaque); +os_close_file(void *opaque) { + strid_t stream = (strid_t) opaque; + assert(opaque); - g_vm->glk_stream_close (stream, nullptr); + g_vm->glk_stream_close(stream, nullptr); } @@ -2981,68 +2789,63 @@ static sc_int gsc_callback(void *opaque, sc_byte *buffer, sc_int length) { * end option. Called on game completion. */ static enum gsc_end_option -gsc_get_ending_option() -{ - sc_char response; - - /* Ensure back to normal style, and update status. */ - gsc_reset_glk_style (); - gsc_status_notify (); - - /* Prompt for restart, undo, or quit. */ - g_vm->glk_put_string ("\nWould you like to RESTART, UNDO a turn, or QUIT? "); - - /* Loop until 'restart', 'undo' or 'quit'. */ - do - { - event_t event; - - do - { - g_vm->glk_request_char_event (gsc_main_window); - gsc_event_wait (evtype_CharInput, &event); - } - while (event.val1 > UCHAR_MAX); - response = g_vm->glk_char_to_upper (event.val1); - } - while (response != 'R' && response != 'U' && response != 'Q'); - - /* Echo the confirmation response, and a new line. */ - g_vm->glk_set_style (style_Input); - switch (response) - { - case 'R': - g_vm->glk_put_string ("Restart"); - break; - case 'U': - g_vm->glk_put_string ("Undo"); - break; - case 'Q': - g_vm->glk_put_string ("Quit"); - break; - default: - gsc_fatal ("GLK: Invalid response encountered"); - g_vm->glk_exit (); - } - g_vm->glk_set_style (style_Normal); - g_vm->glk_put_char ('\n'); - - /* Return the appropriate value for response. */ - switch (response) - { - case 'R': - return GAME_RESTART; - case 'U': - return GAME_UNDO; - case 'Q': - return GAME_QUIT; - default: - gsc_fatal ("GLK: Invalid response encountered"); - g_vm->glk_exit (); - } - - /* Unreachable; supplied to suppress compiler warning. */ - return GAME_QUIT; +gsc_get_ending_option() { + sc_char response; + + /* Ensure back to normal style, and update status. */ + gsc_reset_glk_style(); + gsc_status_notify(); + + /* Prompt for restart, undo, or quit. */ + g_vm->glk_put_string("\nWould you like to RESTART, UNDO a turn, or QUIT? "); + + /* Loop until 'restart', 'undo' or 'quit'. */ + do + { + event_t event; + + do + { + g_vm->glk_request_char_event(gsc_main_window); + gsc_event_wait(evtype_CharInput, &event); + } while (event.val1 > UCHAR_MAX); + response = g_vm->glk_char_to_upper(event.val1); + } while (response != 'R' && response != 'U' && response != 'Q'); + + /* Echo the confirmation response, and a new line. */ + g_vm->glk_set_style(style_Input); + switch (response) { + case 'R': + g_vm->glk_put_string("Restart"); + break; + case 'U': + g_vm->glk_put_string("Undo"); + break; + case 'Q': + g_vm->glk_put_string("Quit"); + break; + default: + gsc_fatal("GLK: Invalid response encountered"); + g_vm->glk_exit(); + } + g_vm->glk_set_style(style_Normal); + g_vm->glk_put_char('\n'); + + /* Return the appropriate value for response. */ + switch (response) { + case 'R': + return GAME_RESTART; + case 'U': + return GAME_UNDO; + case 'Q': + return GAME_QUIT; + default: + gsc_fatal("GLK: Invalid response encountered"); + g_vm->glk_exit(); + } + + /* Unreachable; supplied to suppress compiler warning. */ + return GAME_QUIT; } @@ -3057,16 +2860,14 @@ gsc_get_ending_option() */ static int gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream, - sc_uint trace_flags, sc_bool enable_debugger, - sc_bool stable_random, const sc_char *locale) -{ + sc_uint trace_flags, sc_bool enable_debugger, + sc_bool stable_random, const sc_char *locale) { winid_t window; assert(game_stream); /* Open a temporary Glk main window. */ window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0); - if (window) - { + if (window) { /* Clear and initialize the temporary window. */ g_vm->glk_window_clear(window); g_vm->glk_set_window(window); @@ -3113,42 +2914,35 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream */ sc_set_trace_flags(trace_flags); gsc_game = sc_game_from_callback(gsc_callback, game_stream); - if (!gsc_game) - { + if (!gsc_game) { gsc_game = nullptr; gsc_game_message = "Unable to load an Adrift game from the requested file."; - } - else + } else gsc_game_message = nullptr; /* * If the game was created successfully and there is a restore stream, try * to immediately restore the game from that stream. */ - if (gsc_game && restore_stream) - { - if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream)) - { + if (gsc_game && restore_stream) { + if (!sc_load_game_from_callback(gsc_game, gsc_callback, restore_stream)) { sc_free_game(gsc_game); gsc_game = nullptr; gsc_game_message = "Unable to restore this Adrift game from the requested file."; - } - else + } else gsc_game_message = nullptr; } if (restore_stream) g_vm->glk_stream_close(restore_stream, nullptr); /* If successful, set game debugging and synchronize to the core's locale. */ - if (gsc_game) - { + if (gsc_game) { sc_set_game_debugger_enabled(gsc_game, enable_debugger); gsc_set_locale(sc_get_locale()); } /* Set portable and predictable random number generation if requested. */ - if (stable_random) - { + if (stable_random) { sc_set_portable_random(TRUE); sc_reseed_random_sequence(1); } @@ -3167,126 +2961,112 @@ gsc_startup_code(Common::SeekableReadStream *game_stream, strid_t restore_stream } static void -gsc_main() -{ - sc_bool is_running; - - /* Ensure SCARE internal types have the right sizes. */ - if (!(sizeof (sc_byte) == 1 && sizeof (sc_char) == 1 - && sizeof (sc_uint) >= 4 && sizeof (sc_int) >= 4 - && sizeof (sc_uint) <= 8 && sizeof (sc_int) <= 8)) - { - gsc_fatal ("GLK: Types sized incorrectly, recompilation is needed"); - g_vm->glk_exit (); - } - - /* Create the Glk window, and set its stream as the current one. */ - gsc_main_window = g_vm->glk_window_open (0, 0, 0, wintype_TextBuffer, 0); - if (!gsc_main_window) - { - gsc_fatal ("GLK: Can't open main window"); - g_vm->glk_exit (); - } - g_vm->glk_window_clear (gsc_main_window); - g_vm->glk_set_window (gsc_main_window); - g_vm->glk_set_style (style_Normal); - - /* If there's a problem with the game file, complain now. */ - if (!gsc_game) - { - assert (gsc_game_message); - gsc_header_string ("Glk SCARE Error\n\n"); - gsc_normal_string (gsc_game_message); - gsc_normal_char ('\n'); - g_vm->glk_exit (); - } - - /* Try to create a one-line status window. We can live without it. */ - g_vm->glk_stylehint_set (wintype_TextGrid, style_User1, stylehint_ReverseColor, 1); - gsc_status_window = g_vm->glk_window_open (gsc_main_window, - winmethod_Above | winmethod_Fixed, - 1, wintype_TextGrid, 0); - - /* Repeat the game until no more restarts requested. */ - is_running = TRUE; - while (is_running) - { - /* Run the game until it ends, or the user quits. */ - gsc_status_notify (); - sc_interpret_game (gsc_game); - - /* - * If the game did not complete, the user quit explicitly, so leave the - * game repeat loop. - */ - if (!sc_has_game_completed (gsc_game)) - { - is_running = FALSE; - break; - } - - /* - * If reading from an input log, close it now. We need to request a - * user selection, probably modal, and after that we probably don't - * want the follow-on readlog data being used as game input. - */ - if (gsc_readlog_stream) - { - g_vm->glk_stream_close (gsc_readlog_stream, nullptr); - gsc_readlog_stream = nullptr; - } - - /* - * Get user selection of restart, undo a turn, or quit completed game. - * If undo is unavailable (this should not be possible), degrade to - * restart. - */ - switch (gsc_get_ending_option ()) - { - case GAME_RESTART: - gsc_short_delay (); - sc_restart_game (gsc_game); - break; - - case GAME_UNDO: - if (sc_is_game_undo_available (gsc_game)) - { - sc_undo_game_turn (gsc_game); - gsc_normal_string ("The previous turn has been undone.\n"); - } - else - { - gsc_normal_string ("Sorry, no undo is available.\n"); - gsc_short_delay (); - sc_restart_game (gsc_game); - } - break; - - case GAME_QUIT: - is_running = FALSE; - break; - } - } - - /* All done -- release game resources. */ - sc_free_game (gsc_game); - - /* Close any open transcript, input log, and/or read log. */ - if (gsc_transcript_stream) - { - g_vm->glk_stream_close (gsc_transcript_stream, nullptr); - gsc_transcript_stream = nullptr; - } - if (gsc_inputlog_stream) - { - g_vm->glk_stream_close (gsc_inputlog_stream, nullptr); - gsc_inputlog_stream = nullptr; - } - if (gsc_readlog_stream) - { - g_vm->glk_stream_close (gsc_readlog_stream, nullptr); - gsc_readlog_stream = nullptr; - } +gsc_main() { + sc_bool is_running; + + /* Ensure SCARE internal types have the right sizes. */ + if (!(sizeof(sc_byte) == 1 && sizeof(sc_char) == 1 + && sizeof(sc_uint) >= 4 && sizeof(sc_int) >= 4 + && sizeof(sc_uint) <= 8 && sizeof(sc_int) <= 8)) { + gsc_fatal("GLK: Types sized incorrectly, recompilation is needed"); + g_vm->glk_exit(); + } + + /* Create the Glk window, and set its stream as the current one. */ + gsc_main_window = g_vm->glk_window_open(0, 0, 0, wintype_TextBuffer, 0); + if (!gsc_main_window) { + gsc_fatal("GLK: Can't open main window"); + g_vm->glk_exit(); + } + g_vm->glk_window_clear(gsc_main_window); + g_vm->glk_set_window(gsc_main_window); + g_vm->glk_set_style(style_Normal); + + /* If there's a problem with the game file, complain now. */ + if (!gsc_game) { + assert(gsc_game_message); + gsc_header_string("Glk SCARE Error\n\n"); + gsc_normal_string(gsc_game_message); + gsc_normal_char('\n'); + g_vm->glk_exit(); + } + + /* Try to create a one-line status window. We can live without it. */ + g_vm->glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_ReverseColor, 1); + gsc_status_window = g_vm->glk_window_open(gsc_main_window, + winmethod_Above | winmethod_Fixed, + 1, wintype_TextGrid, 0); + + /* Repeat the game until no more restarts requested. */ + is_running = TRUE; + while (is_running) { + /* Run the game until it ends, or the user quits. */ + gsc_status_notify(); + sc_interpret_game(gsc_game); + + /* + * If the game did not complete, the user quit explicitly, so leave the + * game repeat loop. + */ + if (!sc_has_game_completed(gsc_game)) { + is_running = FALSE; + break; + } + + /* + * If reading from an input log, close it now. We need to request a + * user selection, probably modal, and after that we probably don't + * want the follow-on readlog data being used as game input. + */ + if (gsc_readlog_stream) { + g_vm->glk_stream_close(gsc_readlog_stream, nullptr); + gsc_readlog_stream = nullptr; + } + + /* + * Get user selection of restart, undo a turn, or quit completed game. + * If undo is unavailable (this should not be possible), degrade to + * restart. + */ + switch (gsc_get_ending_option()) { + case GAME_RESTART: + gsc_short_delay(); + sc_restart_game(gsc_game); + break; + + case GAME_UNDO: + if (sc_is_game_undo_available(gsc_game)) { + sc_undo_game_turn(gsc_game); + gsc_normal_string("The previous turn has been undone.\n"); + } else { + gsc_normal_string("Sorry, no undo is available.\n"); + gsc_short_delay(); + sc_restart_game(gsc_game); + } + break; + + case GAME_QUIT: + is_running = FALSE; + break; + } + } + + /* All done -- release game resources. */ + sc_free_game(gsc_game); + + /* Close any open transcript, input log, and/or read log. */ + if (gsc_transcript_stream) { + g_vm->glk_stream_close(gsc_transcript_stream, nullptr); + gsc_transcript_stream = nullptr; + } + if (gsc_inputlog_stream) { + g_vm->glk_stream_close(gsc_inputlog_stream, nullptr); + gsc_inputlog_stream = nullptr; + } + if (gsc_readlog_stream) { + g_vm->glk_stream_close(gsc_readlog_stream, nullptr); + gsc_readlog_stream = nullptr; + } } @@ -3325,21 +3105,33 @@ void adrift_main() { * Glk arguments for UNIX versions of the Glk interpreter. */ glkunix_argumentlist_t glkunix_arguments[] = { - {(char *) "-nc", glkunix_arg_NoValue, - (char *) "-nc No local handling for Glk special commands"}, - {(char *) "-na", glkunix_arg_NoValue, - (char *) "-na Turn off abbreviation expansions"}, - {(char *) "-nu", glkunix_arg_NoValue, - (char *) "-nu Turn off any use of Unicode output"}, + { + (char *) "-nc", glkunix_arg_NoValue, + (char *) "-nc No local handling for Glk special commands" + }, + { + (char *) "-na", glkunix_arg_NoValue, + (char *) "-na Turn off abbreviation expansions" + }, + { + (char *) "-nu", glkunix_arg_NoValue, + (char *) "-nu Turn off any use of Unicode output" + }, #ifdef LINUX_GRAPHICS - {(char *) "-ng", glkunix_arg_NoValue, - (char *) "-ng Turn off attempts at game graphics"}, + { + (char *) "-ng", glkunix_arg_NoValue, + (char *) "-ng Turn off attempts at game graphics" + }, #endif - {(char *) "-r", glkunix_arg_ValueFollows, - (char *) "-r FILE Restore from FILE on starting the game"}, - {(char *) "", glkunix_arg_ValueCanFollow, - (char *) "filename game to run"}, - {nullptr, glkunix_arg_End, nullptr} + { + (char *) "-r", glkunix_arg_ValueFollows, + (char *) "-r FILE Restore from FILE on starting the game" + }, + { + (char *) "", glkunix_arg_ValueCanFollow, + (char *) "filename game to run" + }, + {nullptr, glkunix_arg_End, nullptr} }; #endif |