X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Ffrotz%2Fglkscreen.c;h=2d72bfdd11ae8f66b690df268ec0b04d26821bfd;hb=a3d8dbef8ec2442280d6085d43601bf4ba6cadf9;hp=2773c0753551d85794a3c806efa7329095a869d9;hpb=1176f89bd245d6b6e8120e9fff55550eae733fbb;p=projects%2Fchimara%2Fchimara.git diff --git a/interpreters/frotz/glkscreen.c b/interpreters/frotz/glkscreen.c index 2773c07..2d72bfd 100644 --- a/interpreters/frotz/glkscreen.c +++ b/interpreters/frotz/glkscreen.c @@ -1,6 +1,7 @@ /****************************************************************************** * * * Copyright (C) 2006-2009 by Tor Andersson. * + * Copyright (C) 2010 by Ben Cressey, Chris Spiegel. * * * * This file is part of Gargoyle. * * * @@ -27,16 +28,18 @@ #include "glkfrotz.h" -static unsigned char statusline[256]; +static zchar statusline[256]; static int oldstyle = 0; static int curstyle = 0; -static int upperstyle = 0; -static int lowerstyle = 0; static int cury = 1; static int curx = 1; +static int fixforced = 0; -int curr_fg = 0; -int curr_bg = 0; +static int curr_fg = -2; +static int curr_bg = -2; +static int curr_font = 1; +static int prev_font = 1; +static int temp_font = 0; /* To make the common code happy */ @@ -57,6 +60,13 @@ int os_string_width (const zchar *s) return width; } +int os_string_length (zchar *s) +{ + int length = 0; + while (*s++) length++; + return length; +} + void os_prepare_sample (int a) { glk_sound_load_hint(a, 1); @@ -155,19 +165,26 @@ void reset_status_ht(void) { glk_window_get_size(gos_upper, NULL, &height); if (mach_status_ht != height) + { glk_window_set_arrangement( glk_window_get_parent(gos_upper), winmethod_Above | winmethod_Fixed, mach_status_ht, NULL); + } } } -void erase_window (int w) +void erase_window (zword w) { if (w == 0) glk_window_clear(gos_lower); else if (gos_upper) { +#ifdef GARGLK + garglk_set_reversevideo_stream( + glk_window_get_stream(gos_upper), + TRUE); +#endif /* GARGLK */ memset(statusline, ' ', sizeof statusline); glk_window_clear(gos_upper); reset_status_ht(); @@ -175,7 +192,7 @@ void erase_window (int w) } } -void split_window (int lines) +void split_window (zword lines) { if (!gos_upper) return; @@ -219,11 +236,13 @@ void restart_screen (void) * so ... split status text into regions, reformat and print anew. */ -void packspaces(unsigned char *src, unsigned char *dst) +void packspaces(zchar *src, zchar *dst) { int killing = 0; while (*src) { + if (*src == 0x20202020) + *src = ' '; if (*src == ' ') killing++; else @@ -238,17 +257,15 @@ void packspaces(unsigned char *src, unsigned char *dst) void smartstatusline (void) { - unsigned char packed[256]; - unsigned char buf[256]; - unsigned char *a, *b, *c, *d; + zchar packed[256]; + zchar buf[256]; + zchar *a, *b, *c, *d; int roomlen, scorelen, scoreofs; - int len; - - statusline[curx - 1] = 0; /* terminate! */ + int len, tmp; packspaces(statusline, packed); //strcpy(packed, statusline); - len = strlen(packed); + len = os_string_length(packed); a = packed; while (a[0] == ' ') @@ -279,15 +296,16 @@ void smartstatusline (void) if (scoreofs <= roomlen) scoreofs = roomlen + 2; - memset(buf, ' ', h_screen_cols); - memcpy(buf + 1 + scoreofs, c, scorelen); - memcpy(buf + 1, a, roomlen); + for (tmp = 0; tmp < h_screen_cols; tmp++) + buf[tmp] = ' '; + + memcpy(buf + 1 + scoreofs, c, scorelen * sizeof(zchar)); + memcpy(buf + 1, a, roomlen * sizeof(zchar)); //if (roomlen >= scoreofs) // buf[roomlen + 1] = '|'; glk_window_move_cursor(gos_upper, 0, 0); - glk_set_style(style_User1); - glk_put_buffer(buf, h_screen_cols); + glk_put_buffer_uni(buf, h_screen_cols); glk_window_move_cursor(gos_upper, cury - 1, curx - 1); } @@ -305,24 +323,20 @@ void screen_char (zchar c) return; } - if (gos_upper && gos_curwin == gos_upper) { - if (cury > mach_status_ht) { - mach_status_ht = cury; - reset_status_ht(); - } - } - /* check fixed flag in header, game can change it at whim */ - if (gos_curwin == gos_lower) + int forcefix = ((h_flags & FIXED_FONT_FLAG) != 0); + int curfix = ((curstyle & FIXED_WIDTH_STYLE) != 0); + if (forcefix && !curfix) { - static int forcefix = -1; - int curfix = h_flags & FIXED_FONT_FLAG; - if (forcefix != curfix) - { - forcefix = curfix; - zargs[0] = 0xf000; /* tickle tickle! */ - z_set_text_style(); - } + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); + fixforced = TRUE; + } + else if (!forcefix && fixforced) + { + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); + fixforced = FALSE; } if (gos_upper && gos_curwin == gos_upper) @@ -335,22 +349,38 @@ void screen_char (zchar c) else { if (cury == 1) { - if (curx < sizeof statusline) + if (curx <= ((sizeof statusline / sizeof(zchar)) - 1)) + { statusline[curx - 1] = c; - curx++; - if (curx <= h_screen_cols) - glk_put_char(c); + statusline[curx] = 0; + } + if (curx < h_screen_cols) + { + glk_put_char_uni(c); + } + else if (curx == h_screen_cols) + { + glk_put_char_uni(c); + glk_window_move_cursor(gos_curwin, curx-1, cury-1); + } else + { smartstatusline(); + } + curx ++; } else { - glk_put_char(c); - curx++; - if (curx > h_screen_cols) { - curx = 1; - cury++; + if (curx < h_screen_cols) + { + glk_put_char_uni(c); + } + else if (curx == (h_screen_cols)) + { + glk_put_char_uni(c); + glk_window_move_cursor(gos_curwin, curx-1, cury-1); } + curx++; } } } @@ -358,7 +388,7 @@ void screen_char (zchar c) { if (c == ZC_RETURN) glk_put_char('\n'); - else glk_put_char(c); + else glk_put_char_uni(c); } } @@ -412,6 +442,18 @@ void z_buffer_mode (void) { } +/* + * z_buffer_screen, set the screen buffering mode. + * + * zargs[0] = mode + * + */ + +void z_buffer_screen (void) +{ + store (0); +} + /* * z_erase_line, erase the line starting at the cursor position. * @@ -534,6 +576,59 @@ void z_print_table (void) } } +#define zB(i) ((((i >> 10) & 0x1F) << 3) | (((i >> 10) & 0x1F) >> 2)) +#define zG(i) ((((i >> 5) & 0x1F) << 3) | (((i >> 5) & 0x1F) >> 2)) +#define zR(i) ((((i ) & 0x1F) << 3) | (((i ) & 0x1F) >> 2)) + +#define zRGB(i) (zR(i) << 16 | zG(i) << 8 | zB(i)) + +/* + * z_set_true_colour, set the foreground and background colours + * to specific RGB colour values. + * + * zargs[0] = foreground colour + * zargs[1] = background colour + * zargs[2] = window (-3 is the current one, optional) + * + */ + +void z_set_true_colour (void) +{ + int zfore = zargs[0]; + int zback = zargs[1]; + + if (!(zfore < 0)) + zfore = zRGB(zargs[0]); + + if (!(zback < 0)) + zback = zRGB(zargs[1]); + +#ifdef GARGLK + garglk_set_zcolors(zfore, zback); +#endif /* GARGLK */ + + curr_fg = zfore; + curr_bg = zback; +} + +static int zcolor_map[] = { + -2, /* 0 = current */ + -1, /* 1 = default */ + 0x0000, /* 2 = black */ + 0x001D, /* 3 = red */ + 0x0340, /* 4 = green */ + 0x03BD, /* 5 = yellow */ + 0x59A0, /* 6 = blue */ + 0x7C1F, /* 7 = magenta */ + 0x77A0, /* 8 = cyan */ + 0x7FFF, /* 9 = white */ + 0x5AD6, /* 10 = light grey */ + 0x4631, /* 11 = medium grey */ + 0x2D6B, /* 12 = dark grey */ +}; + +#define zcolor_NUMCOLORS (13) + /* * z_set_colour, set the foreground and background colours. * @@ -548,12 +643,41 @@ void z_set_colour (void) int zfore = zargs[0]; int zback = zargs[1]; + switch (zfore) + { + case -1: + zfore = -3; + + case 0: + case 1: + zfore = zcolor_map[zfore]; + break; + + default: + if (zfore < zcolor_NUMCOLORS) + zfore = zRGB(zcolor_map[zfore]); + break; + } + + switch (zback) + { + case -1: + zback = -3; + + case 0: + case 1: + zback = zcolor_map[zback]; + break; + + default: + if (zback < zcolor_NUMCOLORS) + zback = zRGB(zcolor_map[zback]); + break; + } - if (!(zfore == 0 && zback == 0)) { #ifdef GARGLK - garglk_set_zcolors(zfore, zback); + garglk_set_zcolors(zfore, zback); #endif /* GARGLK */ - } curr_fg = zfore; curr_bg = zback; @@ -568,6 +692,41 @@ void z_set_colour (void) void z_set_font (void) { + zword font = zargs[0]; + + switch (font) + { + case 0: /* previous font */ + temp_font = curr_font; + curr_font = prev_font; + prev_font = temp_font; + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); + store (curr_font); + break; + + case 1: /* normal font */ + prev_font = curr_font; + curr_font = 1; + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); + store (prev_font); + break; + + case 4: /* fixed-pitch font*/ + prev_font = curr_font; + curr_font = 4; + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); + store (prev_font); + break; + + case 2: /* picture font, undefined per 1.1 */ + case 3: /* character graphics font */ + default: /* unavailable */ + store (0); + break; + } } /* @@ -583,8 +742,15 @@ void z_set_cursor (void) { cury = zargs[0]; curx = zargs[1]; - if (gos_upper) + + if (gos_upper) { + if (cury > mach_status_ht) { + mach_status_ht = cury; + reset_status_ht(); + } + glk_window_move_cursor(gos_upper, curx - 1, cury - 1); + } } /* @@ -603,7 +769,7 @@ void z_set_text_style (void) else if (zargs[0] != 0xf000) /* not tickle time */ curstyle |= zargs[0]; - if (h_flags & FIXED_FONT_FLAG) + if (h_flags & FIXED_FONT_FLAG || curr_font == 4) style = curstyle | FIXED_WIDTH_STYLE; else style = curstyle; @@ -613,29 +779,41 @@ void z_set_text_style (void) if (style & REVERSE_STYLE) { - if (gos_curwin == gos_upper && gos_upper) { - glk_set_style(style_User1); - } #ifdef GARGLK garglk_set_reversevideo(TRUE); #endif /* GARGLK */ } - else if (style & FIXED_WIDTH_STYLE) - glk_set_style(style_Preformatted); - else if (style & BOLDFACE_STYLE && style & EMPHASIS_STYLE) - glk_set_style(style_Alert); - else if (style & BOLDFACE_STYLE) - glk_set_style(style_Subheader); - else if (style & EMPHASIS_STYLE) - glk_set_style(style_Emphasized); + + if (style & FIXED_WIDTH_STYLE) + { + if (style & BOLDFACE_STYLE && style & EMPHASIS_STYLE) + glk_set_style(style_BlockQuote); /* monoz */ + else if (style & EMPHASIS_STYLE) + glk_set_style(style_Alert); /* monoi */ + else if (style & BOLDFACE_STYLE) + glk_set_style(style_Subheader); /* monob */ + else + glk_set_style(style_Preformatted); /* monor */ + } else - glk_set_style(style_Normal); + { + if (style & BOLDFACE_STYLE && style & EMPHASIS_STYLE) + glk_set_style(style_Note); /* propz */ + else if (style & EMPHASIS_STYLE) + glk_set_style(style_Emphasized); /* propi */ + else if (style & BOLDFACE_STYLE) + glk_set_style(style_Header); /* propb */ + else + glk_set_style(style_Normal); /* propr */ + } - if (curstyle == 0) { + if (curstyle == 0) + { #ifdef GARGLK garglk_set_reversevideo(FALSE); #endif /* GARGLK */ } + } /* @@ -649,29 +827,25 @@ void z_set_window (void) { int win = zargs[0]; - if (gos_curwin == gos_lower) - lowerstyle = curstyle; - else - upperstyle = curstyle; - if (win == 0) { glk_set_window(gos_lower); gos_curwin = gos_lower; - curstyle = lowerstyle; } else { if (gos_upper) glk_set_window(gos_upper); gos_curwin = gos_upper; - curstyle = upperstyle; } - if (win == 0) - enable_scripting = TRUE; - else - enable_scripting = FALSE; + if (win == 0) + enable_scripting = TRUE; + else + enable_scripting = FALSE; + + zargs[0] = 0xf000; /* tickle tickle! */ + z_set_text_style(); } /* @@ -722,9 +896,12 @@ void z_show_status (void) glk_set_window(gos_upper); gos_curwin = gos_upper; +#ifdef GARGLK + garglk_set_reversevideo(TRUE); +#endif /* GARGLK */ + curx = cury = 1; glk_window_move_cursor(gos_upper, 0, 0); - glk_set_style(style_User1); /* If the screen width is below 55 characters then we have to use the brief status line format */