2 * $Id: dumb-output.c,v 1.2 2002/03/26 22:52:31 feedle Exp $
4 * Copyright 1997,1998 Alfresco Petrofsky <alfresco@petrofsky.berkeley.edu>.
5 * Any use permitted provided this notice stays intact.
7 * Changes for Rockbox copyright 2009 Torne Wuff
9 * Rockbox is not really a dumb terminal (it supports printing text wherever
10 * you like) but it doesn't implement a terminal type buffer, so this is
11 * close enough to be a good starting point. Keeping a copy of the graphical
12 * framebuffer would be too expensive, text+attributes is much smaller.
15 #include "dumb_frotz.h"
17 /* The in-memory state of the screen. */
18 /* Each cell contains a style in the upper byte and a char in the lower. */
19 typedef unsigned short cell
;
20 static cell screen_data
[(LCD_WIDTH
/SYSFONT_WIDTH
) * (LCD_HEIGHT
/SYSFONT_HEIGHT
)];
22 static cell
make_cell(int style
, char c
) {return (style
<< 8) | (0xff & c
);}
23 static char cell_char(cell c
) {return c
& 0xff;}
24 static int cell_style(cell c
) {return c
>> 8;}
26 static int current_style
= 0;
27 static int cursor_row
= 0, cursor_col
= 0;
29 static cell
*dumb_row(int r
) {return screen_data
+ r
* h_screen_cols
;}
31 int os_char_width (zchar z
)
37 int os_string_width (const zchar
*s
)
42 while ((c
= *s
++) != 0)
43 if (c
== ZC_NEW_STYLE
|| c
== ZC_NEW_FONT
)
46 width
+= os_char_width(c
);
51 void os_set_cursor(int row
, int col
)
53 cursor_row
= row
- 1; cursor_col
= col
- 1;
54 if (cursor_row
>= h_screen_rows
)
55 cursor_row
= h_screen_rows
- 1;
59 static void dumb_set_cell(int row
, int col
, cell c
)
61 dumb_row(row
)[col
] = c
;
64 void os_set_text_style(int x
)
66 current_style
= x
& REVERSE_STYLE
;
69 static void dumb_display_cell(int row
, int col
)
71 cell cel
= dumb_row(row
)[col
];
72 char c
= cell_char(cel
);
75 char style
= cell_style(cel
);
77 char *end
= rb
->utf8encode(c
, s
);
79 if (style
& REVERSE_STYLE
)
80 rb
->lcd_set_drawmode(DRMODE_INVERSEVID
);
81 rb
->lcd_putsxy(col
* SYSFONT_WIDTH
, row
* SYSFONT_HEIGHT
, s
);
82 rb
->lcd_set_drawmode(DRMODE_SOLID
);
85 /* put a character in the cell at the cursor and advance the cursor. */
86 static void dumb_display_char(char c
)
88 dumb_set_cell(cursor_row
, cursor_col
, make_cell(current_style
, c
));
89 if (++cursor_col
== h_screen_cols
) {
90 if (cursor_row
== h_screen_rows
- 1)
99 void os_display_char (zchar c
)
101 if (c
>= ZC_LATIN1_MIN
/*&& c <= ZC_LATIN1_MAX*/) {
102 dumb_display_char(c
);
103 } else if (c
>= 32 && c
<= 126) {
104 dumb_display_char(c
);
105 } else if (c
== ZC_GAP
) {
106 dumb_display_char(' '); dumb_display_char(' ');
107 } else if (c
== ZC_INDENT
) {
108 dumb_display_char(' '); dumb_display_char(' '); dumb_display_char(' ');
114 /* Haxor your boxor? */
115 void os_display_string (const zchar
*s
)
119 while ((c
= *s
++) != 0)
120 if (c
== ZC_NEW_FONT
)
122 else if (c
== ZC_NEW_STYLE
)
123 os_set_text_style(*s
++);
129 void os_erase_area (int top
, int left
, int bottom
, int right
)
132 top
--; left
--; bottom
--; right
--;
133 if (left
== 0 && right
== h_screen_cols
- 1)
134 rb
->memset(dumb_row(top
), 0, (bottom
- top
+ 1) * h_screen_cols
* sizeof(cell
));
136 for (row
= top
; row
<= bottom
; row
++)
137 rb
->memset(dumb_row(row
) + left
, 0, (right
- left
+ 1) * sizeof(cell
));
140 void os_scroll_area (int top
, int left
, int bottom
, int right
, int units
)
143 top
--; left
--; bottom
--; right
--;
145 for (row
= top
; row
<= bottom
- units
; row
++)
146 rb
->memcpy(dumb_row(row
) + left
,
147 dumb_row(row
+ units
) + left
,
148 (right
- left
+ 1) * sizeof(cell
));
149 os_erase_area(bottom
- units
+ 2, left
+ 1, bottom
+ 1, right
+ 1);
150 } else if (units
< 0) {
151 for (row
= bottom
; row
>= top
- units
; row
--)
152 rb
->memcpy(dumb_row(row
) + left
,
153 dumb_row(row
+ units
) + left
,
154 (right
- left
+ 1) * sizeof(cell
));
155 os_erase_area(top
+ 1, left
+ 1, top
- units
, right
+ 1);
159 int os_font_data(int font
, int *height
, int *width
)
161 if (font
== TEXT_FONT
) {
162 *height
= 1; *width
= 1; return 1;
167 void os_set_colour (int x
, int y
) { (void)x
; (void)y
; }
168 void os_set_font (int x
) { (void)x
; }
170 /* Unconditionally show whole screen. */
171 void dumb_dump_screen(void)
174 rb
->lcd_clear_display();
175 for (r
= 0; r
< h_screen_height
; r
++)
176 for (c
= 0; c
< h_screen_width
; c
++)
177 dumb_display_cell(r
, c
);
181 /* Show the current screen contents. */
182 void dumb_show_screen(bool show_cursor
)
188 void os_more_prompt(void)
190 int old_row
= cursor_row
;
191 int old_col
= cursor_col
;
192 int old_style
= current_style
;
194 current_style
= REVERSE_STYLE
;
195 os_display_string("[MORE]");
198 cursor_row
= old_row
;
199 cursor_col
= old_col
;
200 current_style
= old_style
;
201 os_erase_area(cursor_row
+1, cursor_col
+1, cursor_row
+1, cursor_col
+7);
204 void os_reset_screen(void)
206 current_style
= REVERSE_STYLE
;
207 os_display_string("[Press key to exit]");
212 /* To make the common code happy */
214 void os_prepare_sample (int a
) { (void)a
; }
215 void os_finish_with_sample (int a
) { (void)a
; }
216 void os_start_sample (int a
, int b
, int c
, zword d
)
218 (void)a
; (void)b
; (void)c
; (void)d
;
220 void os_stop_sample (int a
) { (void)a
; }
222 void dumb_init_output(void)
224 if (h_version
== V3
) {
225 h_config
|= CONFIG_SPLITSCREEN
;
226 h_flags
&= ~OLD_SOUND_FLAG
;
229 if (h_version
>= V5
) {
230 h_flags
&= ~SOUND_FLAG
;
233 h_screen_height
= h_screen_rows
;
234 h_screen_width
= h_screen_cols
;
236 h_font_width
= 1; h_font_height
= 1;
238 os_erase_area(1, 1, h_screen_rows
, h_screen_cols
);
241 bool os_picture_data(int num
, int *height
, int *width
)
249 void os_draw_picture (int num
, int row
, int col
)
256 int os_peek_colour (void) {return BLACK_COLOUR
; }