1 /* SLang Screen management routines */
2 /* Copyright (c) 1992, 1995 John E. Davis
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Perl Artistic License.
16 typedef struct Screen_Type
18 int n
; /* number of chars written last time */
19 int flags
; /* line untouched, etc... */
20 unsigned short *old
, *neew
;
22 unsigned long old_hash
, new_hash
;
31 #define MAX_SCREEN_SIZE 120
33 #define MAX_SCREEN_SIZE 75
36 Screen_Type SL_Screen
[MAX_SCREEN_SIZE
];
37 static int Start_Col
, Start_Row
;
38 static int Screen_Cols
, Screen_Rows
;
39 static int This_Row
, This_Col
;
40 static int This_Color
; /* only the first 8 bits of this
41 * are used. The highest bit is used
42 * to indicate an alternate character
43 * set. This leaves 127 userdefineable
48 #define ALT_CHAR_FLAG 0x80
50 #define ALT_CHAR_FLAG 0x00
53 int SLsmg_Newline_Moves
= 0;
54 int SLsmg_Backspace_Moves
= 0;
56 static void blank_line (unsigned short *p
, int n
, unsigned char ch
)
58 register unsigned short *pmax
= p
+ n
;
59 register unsigned short color_ch
;
61 color_ch
= (This_Color
<< 8) | (unsigned short) ch
;
70 static void clear_region (int row
, int n
)
75 if (imax
> Screen_Rows
) imax
= Screen_Rows
;
76 for (i
= row
; i
< imax
; i
++)
80 blank_line (SL_Screen
[i
].neew
, Screen_Cols
, ' ');
81 SL_Screen
[i
].flags
|= TOUCHED
;
86 void SLsmg_erase_eol (void)
90 c
= This_Col
- Start_Col
;
91 r
= This_Row
- Start_Row
;
93 if ((r
< 0) || (r
>= Screen_Rows
)) return;
94 if (c
< 0) c
= 0; else if (c
>= Screen_Cols
) return;
95 blank_line (SL_Screen
[This_Row
].neew
+ c
, Screen_Cols
- c
, ' ');
96 SL_Screen
[This_Row
].flags
|= TOUCHED
;
99 static void scroll_up (void)
101 unsigned int i
, imax
;
102 unsigned short *neew
;
104 neew
= SL_Screen
[0].neew
;
105 imax
= Screen_Rows
- 1;
106 for (i
= 0; i
< imax
; i
++)
108 SL_Screen
[i
].neew
= SL_Screen
[i
+ 1].neew
;
109 SL_Screen
[i
].flags
|= TOUCHED
;
111 SL_Screen
[i
].neew
= neew
;
112 SL_Screen
[i
].flags
|= TOUCHED
;
113 blank_line (neew
, Screen_Cols
, ' ');
120 void SLsmg_gotorc (int r
, int c
)
126 int SLsmg_get_row (void)
131 int SLsmg_get_column (void)
136 void SLsmg_erase_eos (void)
139 clear_region (This_Row
+ 1, Screen_Rows
);
142 static int This_Alt_Char
;
145 void SLsmg_set_char_set (int i
)
147 if (SLtt_Use_Blink_For_ACS
) return; /* alt chars not used and the alt bit
148 * is used to indicate a blink.
150 if (i
) This_Alt_Char
= ALT_CHAR_FLAG
;
151 else This_Alt_Char
= 0;
154 This_Color
|= This_Alt_Char
;
158 void SLsmg_set_color (int color
)
160 if (color
< 0) return;
161 This_Color
= color
| This_Alt_Char
;
165 void SLsmg_reverse_video (void)
171 void SLsmg_normal_video (void)
173 This_Color
= This_Alt_Char
; /* reset video but NOT char set. */
177 static int point_visible (int col_too
)
179 return ((This_Row
>= Start_Row
) && (This_Row
< Start_Row
+ Screen_Rows
)
181 || ((This_Col
>= Start_Col
)
182 && (This_Col
< Start_Col
+ Screen_Cols
))));
185 void SLsmg_printf (char *fmt
, ...)
191 (void) g_vsnprintf(p
, sizeof (p
), fmt
, ap
);
194 SLsmg_write_string (p
);
197 void SLsmg_write_string (char *str
)
199 SLsmg_write_nchars (str
, strlen (str
));
202 void SLsmg_write_nstring (char *str
, int n
)
206 if (str
== NULL
) width
= 0;
209 width
= strlen (str
);
210 if (width
> n
) width
= n
;
211 SLsmg_write_nchars (str
, width
);
213 while (width
++ < n
) SLsmg_write_nchars (&blank
, 1);
216 void SLsmg_write_wrapped_string (char *s
, int r
, int c
, int dr
, int dc
, int fill
)
218 register char ch
, *p
;
221 if ((dr
== 0) || (dc
== 0)) return;
227 if ((ch
== 0) || (ch
== '\n'))
234 SLsmg_write_nchars (s
, dc
);
235 if (fill
&& (diff
> 0))
237 while (diff
--) SLsmg_write_char (' ');
239 if ((ch
== 0) || (dr
== 1)) break;
249 SLsmg_write_nchars (s
, dc
+ 1);
263 int SLsmg_Tab_Width
= 8;
265 /* Minimum value for which eight bit char is displayed as is. */
268 int SLsmg_Display_Eight_Bit
= 160;
269 static unsigned char Alt_Char_Set
[129];/* 129th is used as a flag */
271 int SLsmg_Display_Eight_Bit
= 128;
274 void SLsmg_write_nchars (char *str
, int n
)
276 register unsigned short *p
, old
, neew
, color
;
279 int len
, start_len
, max_len
;
283 int alt_char_set_flag
;
285 alt_char_set_flag
= ((SLtt_Use_Blink_For_ACS
== 0)
286 && (This_Color
& ALT_CHAR_FLAG
));
290 color
= This_Color
<< 8;
292 top
: /* get here only on newline */
295 start_len
= Start_Col
;
297 if (point_visible (0) == 0) return;
300 max_len
= start_len
+ Screen_Cols
;
302 p
= SL_Screen
[This_Row
].neew
;
303 if (len
> start_len
) p
+= (len
- start_len
);
305 flags
= SL_Screen
[This_Row
].flags
;
306 while ((len
< max_len
) && (str
< str_max
))
308 ch
= (unsigned char) *str
++;
311 if (alt_char_set_flag
)
312 ch
= Alt_Char_Set
[ch
& 0x7F];
314 if (((ch
>= ' ') && (ch
< 127))
315 || (ch
>= (unsigned char) SLsmg_Display_Eight_Bit
)
325 neew
= color
| (unsigned short) ch
;
335 else if ((ch
== '\t') && (SLsmg_Tab_Width
> 0))
338 n
+= SLsmg_Tab_Width
;
339 n
= SLsmg_Tab_Width
- (n
% SLsmg_Tab_Width
);
340 if (len
+ n
> max_len
) n
= max_len
- len
;
341 neew
= color
| (unsigned short) ' ';
361 else if ((ch
== 0x8) && SLsmg_Backspace_Moves
)
369 neew
= color
| (unsigned short) '~';
379 if (len
== max_len
) break;
387 neew
= color
| (unsigned short) '^';
394 if (len
== max_len
) break;
397 if (ch
== 127) ch
= '?'; else ch
= ch
+ '@';
401 neew
= color
| (unsigned short) ch
;
412 SL_Screen
[This_Row
].flags
= flags
;
415 if (SLsmg_Newline_Moves
== 0)
418 if (newline_flag
== 0)
420 while (str
< str_max
)
422 if (*str
== '\n') break;
425 if (str
== str_max
) return;
431 if (This_Row
== Start_Row
+ Screen_Rows
)
433 if (SLsmg_Newline_Moves
> 0) scroll_up ();
439 void SLsmg_write_char (char ch
)
441 SLsmg_write_nchars (&ch
, 1);
447 void SLsmg_cls (void)
450 clear_region (0, Screen_Rows
);
451 This_Color
= This_Alt_Char
;
455 static void do_copy (unsigned short *a
, unsigned short *b
)
457 unsigned short *amax
= a
+ Screen_Cols
;
459 while (a
< amax
) *a
++ = *b
++;
464 int SLsmg_Scroll_Hash_Border
= 0;
465 static unsigned long compute_hash (unsigned short *s
, int n
)
467 register unsigned long h
= 0, g
;
468 register unsigned long sum
= 0;
469 register unsigned short *smax
, ch
;
472 s
+= SLsmg_Scroll_Hash_Border
;
473 smax
= s
+ (n
- SLsmg_Scroll_Hash_Border
);
477 if (is_blank
&& ((ch
& 0xFF) != 32)) is_blank
--;
482 if ((g
= h
& 0xE0000000UL
) != 0)
488 if (is_blank
) return 0;
492 static unsigned long Blank_Hash
;
494 static void try_scroll (void)
496 int i
, j
, di
, r1
, r2
, rmin
, rmax
;
498 int color
, did_scroll
= 0;
502 /* find region limits. */
504 for (rmax
= Screen_Rows
- 1; rmax
> 0; rmax
--)
506 if (SL_Screen
[rmax
].new_hash
!= SL_Screen
[rmax
].old_hash
)
510 || (SL_Screen
[r1
].new_hash
!= SL_Screen
[r1
].old_hash
))
517 for (rmin
= 0; rmin
< rmax
; rmin
++)
519 if (SL_Screen
[rmin
].new_hash
!= SL_Screen
[rmin
].old_hash
)
523 || (SL_Screen
[r1
].new_hash
!= SL_Screen
[r1
].old_hash
))
531 for (i
= rmax
; i
> rmin
; i
--)
533 hash
= SL_Screen
[i
].new_hash
;
534 if (hash
== Blank_Hash
) continue;
536 if ((hash
== SL_Screen
[i
].old_hash
)
537 || ((i
+ 1 < Screen_Rows
) && (hash
== SL_Screen
[i
+ 1].old_hash
))
538 || ((i
- 1 > rmin
) && (SL_Screen
[i
].old_hash
== SL_Screen
[i
- 1].new_hash
)))
541 for (j
= i
- 1; j
>= rmin
; j
--)
543 if (hash
== SL_Screen
[j
].old_hash
) break;
545 if (j
< rmin
) continue;
547 r2
= i
; /* end scroll region */
552 while ((j
>= rmin
) && (SL_Screen
[j
].old_hash
== SL_Screen
[j
+ di
].new_hash
))
554 if (SL_Screen
[j
].old_hash
== Blank_Hash
) ignore
++;
559 /* If this scroll only scrolls this line into place, don't do it.
561 if ((di
> 1) && (r1
+ di
+ ignore
== r2
)) continue;
563 /* If there is anything in the scrolling region that is ok, abort the
567 for (j
= r1
; j
<= r2
; j
++)
569 if ((SL_Screen
[j
].old_hash
!= Blank_Hash
)
570 && (SL_Screen
[j
].old_hash
== SL_Screen
[j
].new_hash
))
572 /* See if the scroll is happens to scroll this one into place. */
573 if ((j
+ di
> r2
) || (SL_Screen
[j
].old_hash
!= SL_Screen
[j
+ di
].new_hash
))
577 if (j
<= r2
) continue;
579 color
= This_Color
; This_Color
= 0;
581 SLtt_normal_video ();
582 SLtt_set_scroll_region (r1
, r2
);
584 SLtt_reverse_index (di
);
585 SLtt_reset_scroll_region ();
586 /* Now we have a hole in the screen. Make the virtual screen look
589 for (j
= r1
; j
<= r2
; j
++) SL_Screen
[j
].flags
= TOUCHED
;
593 tmp
= SL_Screen
[r2
].old
;
594 for (j
= r2
; j
> r1
; j
--)
596 SL_Screen
[j
].old
= SL_Screen
[j
- 1].old
;
597 SL_Screen
[j
].old_hash
= SL_Screen
[j
- 1].old_hash
;
599 SL_Screen
[r1
].old
= tmp
;
600 blank_line (SL_Screen
[r1
].old
, Screen_Cols
, ' ');
601 SL_Screen
[r1
].old_hash
= Blank_Hash
;
606 if (did_scroll
) return;
608 /* Try other direction */
610 for (i
= rmin
; i
< rmax
; i
++)
612 hash
= SL_Screen
[i
].new_hash
;
613 if (hash
== Blank_Hash
) continue;
614 if (hash
== SL_Screen
[i
].old_hash
) continue;
616 /* find a match further down screen */
617 for (j
= i
+ 1; j
<= rmax
; j
++)
619 if (hash
== SL_Screen
[j
].old_hash
) break;
621 if (j
> rmax
) continue;
623 r1
= i
; /* beg scroll region */
624 di
= j
- i
; /* number of lines to scroll */
625 j
++; /* since we know this is a match */
627 /* find end of scroll region */
629 while ((j
<= rmax
) && (SL_Screen
[j
].old_hash
== SL_Screen
[j
- di
].new_hash
))
631 if (SL_Screen
[j
].old_hash
== Blank_Hash
) ignore
++;
634 r2
= j
- 1; /* end of scroll region */
636 /* If this scroll only scrolls this line into place, don't do it.
638 if ((di
> 1) && (r1
+ di
+ ignore
== r2
)) continue;
640 /* If there is anything in the scrolling region that is ok, abort the
644 for (j
= r1
; j
<= r2
; j
++)
646 if ((SL_Screen
[j
].old_hash
!= Blank_Hash
)
647 && (SL_Screen
[j
].old_hash
== SL_Screen
[j
].new_hash
))
649 if ((j
- di
< r1
) || (SL_Screen
[j
].old_hash
!= SL_Screen
[j
- di
].new_hash
))
654 if (j
<= r2
) continue;
656 color
= This_Color
; This_Color
= 0;
657 SLtt_normal_video ();
658 SLtt_set_scroll_region (r1
, r2
);
659 SLtt_goto_rc (0, 0); /* relative to scroll region */
660 SLtt_delete_nlines (di
);
661 SLtt_reset_scroll_region ();
662 /* Now we have a hole in the screen. Make the virtual screen look
665 for (j
= r1
; j
<= r2
; j
++) SL_Screen
[j
].flags
= TOUCHED
;
669 tmp
= SL_Screen
[r1
].old
;
670 for (j
= r1
; j
< r2
; j
++)
672 SL_Screen
[j
].old
= SL_Screen
[j
+ 1].old
;
673 SL_Screen
[j
].old_hash
= SL_Screen
[j
+ 1].old_hash
;
675 SL_Screen
[r2
].old
= tmp
;
676 blank_line (SL_Screen
[r2
].old
, Screen_Cols
, ' ');
677 SL_Screen
[r2
].old_hash
= Blank_Hash
;
684 #endif /* NOT pc_system */
688 static int Smg_Inited
;
690 void SLsmg_refresh (void)
694 if (Smg_Inited
== 0) return;
696 for (i
= 0; i
< Screen_Rows
; i
++)
698 if (SL_Screen
[i
].flags
== 0) continue;
699 SL_Screen
[i
].new_hash
= compute_hash (SL_Screen
[i
].neew
, Screen_Cols
);
705 SLtt_normal_video (); SLtt_cls ();
708 else if (SLtt_Term_Cannot_Scroll
== 0) try_scroll ();
711 for (i
= 0; i
< Screen_Rows
; i
++)
715 if (SL_Screen
[i
].flags
== 0) continue;
717 if (SL_Screen
[i
].flags
& TRASHED
)
719 SLtt_goto_rc (i
, -1); /* Force cursor to move */
721 if (Cls_Flag
== 0) SLtt_del_eol ();
726 if (Cls_Flag
|| trashed
)
728 int color
= This_Color
;
730 blank_line (SL_Screen
[i
].old
, Screen_Cols
, ' ');
734 SL_Screen
[i
].old
[Screen_Cols
] = 0;
735 SL_Screen
[i
].neew
[Screen_Cols
] = 0;
737 SLtt_smart_puts (SL_Screen
[i
].neew
, SL_Screen
[i
].old
, Screen_Cols
, i
);
739 SLMEMCPY ((char *) SL_Screen
[i
].old
, (char *) SL_Screen
[i
].neew
,
740 Screen_Cols
* sizeof (short));
742 SL_Screen
[i
].flags
= 0;
744 SL_Screen
[i
].old_hash
= SL_Screen
[i
].new_hash
;
748 if (point_visible (1)) SLtt_goto_rc (This_Row
- Start_Row
, This_Col
- Start_Col
);
749 SLtt_flush_output ();
753 static int compute_clip (int row
, int n
, int box_start
, int box_end
,
754 int *rmin
, int *rmax
)
759 if (row
>= box_end
) return 0;
761 if (row_max
<= box_start
) return 0;
763 if (row
< box_start
) row
= box_start
;
764 if (row_max
>= box_end
) row_max
= box_end
;
770 void SLsmg_touch_lines (int row
, int n
)
775 if (0 == compute_clip (row
, n
, Start_Row
, Start_Row
+ Screen_Rows
, &r1
, &r2
))
780 for (i
= r1
; i
< r2
; i
++)
782 SL_Screen
[i
].flags
|= TRASHED
;
787 static char Fake_Alt_Char_Pairs
[] = "a:j+k+l+m+q-t+u+v+w+x|n+`+f\\g#~o,<+>.v-^h#0#";
789 static void init_alt_char_set (void)
792 unsigned char *p
, *pmax
, ch
;
794 if (Alt_Char_Set
[128] == 128) return;
797 memset ((char *)Alt_Char_Set
, ' ', i
);
800 Alt_Char_Set
[i
] = i
;
805 if (SLtt_Has_Alt_Charset
)
807 p
= (unsigned char *) SLtt_Graphics_Char_Pairs
;
808 if (p
== NULL
) return;
810 else p
= (unsigned char *) Fake_Alt_Char_Pairs
;
811 pmax
= p
+ strlen ((char *) p
);
813 /* Some systems have messed up entries for this */
817 ch
&= 0x7F; /* should be unnecessary */
818 Alt_Char_Set
[ch
] = *p
;
825 # define BLOCK_SIGNALS SLsig_block_signals ();
826 # define UNBLOCK_SIGNALS SLsig_unblock_signals ();
828 # define BLOCK_SIGNALS
829 # define UNBLOCK_SIGNALS
832 static int Smg_Suspended
;
833 void SLsmg_suspend_smg (void)
837 if (Smg_Suspended
== 0)
846 void SLsmg_resume_smg (void)
851 if (Smg_Suspended
== 0)
860 for (i
= 0; i
< Screen_Rows
; i
++)
861 SL_Screen
[i
].flags
|= TRASHED
;
867 int SLsmg_init_smg (void)
870 unsigned short *old
, *neew
;
873 if (Smg_Inited
) SLsmg_reset_smg ();
875 Screen_Cols
= SLtt_Screen_Cols
;
876 Screen_Rows
= SLtt_Screen_Rows
;
877 This_Col
= This_Row
= Start_Col
= Start_Row
= 0;
883 init_alt_char_set ();
885 len
= Screen_Cols
+ 3;
886 for (i
= 0; i
< Screen_Rows
; i
++)
888 if ((NULL
== (old
= (unsigned short *) SLMALLOC (sizeof(short) * len
)))
889 || ((NULL
== (neew
= (unsigned short *) SLMALLOC (sizeof(short) * len
)))))
891 SLang_Error
= SL_MALLOC_ERROR
;
895 blank_line (old
, len
, ' ');
896 blank_line (neew
, len
, ' ');
897 SL_Screen
[i
].old
= old
;
898 SL_Screen
[i
].neew
= neew
;
899 SL_Screen
[i
].flags
= 0;
901 Blank_Hash
= compute_hash (old
, Screen_Cols
);
902 SL_Screen
[i
].new_hash
= SL_Screen
[i
].old_hash
= Blank_Hash
;
911 void SLsmg_reset_smg (void)
921 for (i
= 0; i
< Screen_Rows
; i
++)
923 if (SL_Screen
[i
].old
!= NULL
) SLFREE (SL_Screen
[i
].old
);
924 if (SL_Screen
[i
].neew
!= NULL
) SLFREE (SL_Screen
[i
].neew
);
925 SL_Screen
[i
].old
= SL_Screen
[i
].neew
= NULL
;
928 This_Alt_Char
= This_Color
= 0;
935 unsigned short SLsmg_char_at (void)
937 if (point_visible (1))
939 return SL_Screen
[This_Row
- Start_Row
].neew
[This_Col
- Start_Col
];
945 void SLsmg_vprintf (char *fmt
, va_list ap
)
949 (void) g_vsnprintf(p
, sizeof (p
), fmt
, ap
);
951 SLsmg_write_string (p
);
954 void SLsmg_set_screen_start (int *r
, int *c
)
956 int or = Start_Row
, oc
= Start_Col
;
958 if (c
== NULL
) Start_Col
= 0;
964 if (r
== NULL
) Start_Row
= 0;
972 void SLsmg_draw_object (int r
, int c
, unsigned char object
)
974 This_Row
= r
; This_Col
= c
;
976 if (point_visible (1))
978 int color
= This_Color
;
979 This_Color
|= ALT_CHAR_FLAG
;
980 SLsmg_write_char (object
);
987 void SLsmg_draw_hline (int n
)
989 static unsigned char hbuf
[16];
992 int final_col
= This_Col
+ n
;
995 if ((This_Row
< Start_Row
) || (This_Row
>= Start_Row
+ Screen_Rows
)
996 || (0 == compute_clip (This_Col
, n
, Start_Col
, Start_Col
+ Screen_Cols
,
999 This_Col
= final_col
;
1005 SLMEMSET ((char *) hbuf
, SLSMG_HLINE_CHAR
, 16);
1011 save_color
= This_Color
;
1012 This_Color
|= ALT_CHAR_FLAG
;
1015 SLsmg_write_nchars ((char *) hbuf
, n
% 16);
1018 SLsmg_write_nchars ((char *) hbuf
, 16);
1021 This_Color
= save_color
;
1022 This_Col
= final_col
;
1025 void SLsmg_draw_vline (int n
)
1027 unsigned char ch
= SLSMG_VLINE_CHAR
;
1028 int c
= This_Col
, rmin
, rmax
;
1029 int final_row
= This_Row
+ n
;
1032 if (((c
< Start_Col
) || (c
>= Start_Col
+ Screen_Cols
)) ||
1033 (0 == compute_clip (This_Row
, n
, Start_Row
, Start_Row
+ Screen_Rows
,
1036 This_Row
= final_row
;
1040 save_color
= This_Color
;
1041 This_Color
|= ALT_CHAR_FLAG
;
1043 for (This_Row
= rmin
; This_Row
< rmax
; This_Row
++)
1046 SLsmg_write_nchars ((char *) &ch
, 1);
1049 This_Col
= c
; This_Row
= final_row
;
1050 This_Color
= save_color
;
1053 void SLsmg_draw_box (int r
, int c
, int dr
, int dc
)
1055 if (!dr
|| !dc
) return;
1056 This_Row
= r
; This_Col
= c
;
1058 SLsmg_draw_hline (dc
);
1059 SLsmg_draw_vline (dr
);
1060 This_Row
= r
; This_Col
= c
;
1061 SLsmg_draw_vline (dr
);
1062 SLsmg_draw_hline (dc
);
1063 SLsmg_draw_object (r
, c
, SLSMG_ULCORN_CHAR
);
1064 SLsmg_draw_object (r
, c
+ dc
, SLSMG_URCORN_CHAR
);
1065 SLsmg_draw_object (r
+ dr
, c
, SLSMG_LLCORN_CHAR
);
1066 SLsmg_draw_object (r
+ dr
, c
+ dc
, SLSMG_LRCORN_CHAR
);
1067 This_Row
= r
; This_Col
= c
;
1070 void SLsmg_fill_region (int r
, int c
, int dr
, int dc
, unsigned char ch
)
1072 static unsigned char hbuf
[16];
1077 if ((dc
< 0) || (dr
< 0)) return;
1079 SLsmg_gotorc (r
, c
);
1080 r
= This_Row
; c
= This_Col
;
1082 dcmax
= Screen_Cols
- This_Col
;
1083 if (dc
> dcmax
) dc
= dcmax
;
1085 rmax
= This_Row
+ dr
;
1086 if (rmax
> Screen_Rows
) rmax
= Screen_Rows
;
1089 ch
= Alt_Char_Set
[ch
];
1091 if (ch
!= hbuf
[0]) SLMEMSET ((char *) hbuf
, (char) ch
, 16);
1093 for (This_Row
= r
; This_Row
< rmax
; This_Row
++)
1097 SLsmg_write_nchars ((char *) hbuf
, dc
% 16);
1100 SLsmg_write_nchars ((char *) hbuf
, 16);
1107 void SLsmg_forward (int n
)
1112 void SLsmg_write_color_chars (unsigned short *s
, unsigned int len
)
1114 unsigned short *smax
, sh
;
1115 char buf
[32], *b
, *bmax
;
1116 int color
, save_color
;
1120 bmax
= b
+ sizeof (buf
);
1122 save_color
= This_Color
;
1129 if ((color
!= This_Color
) || (b
== bmax
))
1133 SLsmg_write_nchars (buf
, (int) (b
- buf
));
1138 *b
++ = (char) (sh
& 0xFF);
1142 SLsmg_write_nchars (buf
, (int) (b
- buf
));
1144 This_Color
= save_color
;
1147 unsigned int SLsmg_read_raw (unsigned short *buf
, unsigned int len
)
1151 if (0 == point_visible (1)) return 0;
1153 r
= (unsigned int) (This_Row
- Start_Row
);
1154 c
= (unsigned int) (This_Col
- Start_Col
);
1156 if (c
+ len
> (unsigned int) Screen_Cols
)
1157 len
= (unsigned int) Screen_Cols
- c
;
1159 memcpy ((char *) buf
, (char *) (SL_Screen
[r
].neew
+ c
), len
* sizeof (short));
1163 unsigned int SLsmg_write_raw (unsigned short *buf
, unsigned int len
)
1166 unsigned short *dest
;
1168 if (0 == point_visible (1)) return 0;
1170 r
= (unsigned int) (This_Row
- Start_Row
);
1171 c
= (unsigned int) (This_Col
- Start_Col
);
1173 if (c
+ len
> (unsigned int) Screen_Cols
)
1174 len
= (unsigned int) Screen_Cols
- c
;
1176 dest
= SL_Screen
[r
].neew
+ c
;
1178 if (0 != memcmp ((char *) dest
, (char *) buf
, len
* sizeof (short)))
1180 memcpy ((char *) dest
, (char *) buf
, len
* sizeof (short));
1181 SL_Screen
[r
].flags
|= TOUCHED
;