1 /*
2 Shared
3 */
4
5 #include "shared.h"
6
7 #include "config.h"
8 #include "console.h"
9 #include "file.h"
10 #include "head.h"
11 #include "os.h"
12 #include "page.h"
13 #include "wio.h"
14
15 #define CMD_LIMIT 256
16
display(byte * s)17 void display(byte *s)
18 {
19 start_update();
20 while(*s)
21 out_char(*s++);
22 finish_update();
23 }
24
save_cursor(void)25 void save_cursor(void)
26 {
27 save_attributes(0);
28 }
29
restore_cursor(void)30 void restore_cursor(void)
31 {
32 restore_attributes(0);
33 }
34
35 #define bytes(s) (1+os_strlen(s))
36
draw_editable(int x,byte * s,int off,int log)37 static void draw_editable(int x, byte *s, int off, int log)
38 {
39 int dummy, y;
40 get_xy(&dummy, &y);
41 start_update();
42 set_xy(x, y);
43 erase_to_eoln();
44 if(log)
45 display(s);
46 else
47 raw_display(s);
48 set_xy(x + off, y);
49 finish_update();
50 }
51
getline(const byte * prompt,char * buff,int maxlen)52 int getline(const byte *prompt, char *buff, int maxlen)
53 {
54 static int cmd_held = 0;
55 static char cmd_buff[CMD_LIMIT];
56 int cmd_count = cmd_held;
57 int font = 1;
58 int c, off = 0;
59 int x, y;
60 force_update();
61 show_cursor();
62 raw_display(prompt);
63 swap_font_status(&font);
64 get_xy(&x, &y);
65 buff[off] = '\0';
66 draw_editable(x, (byte *) buff, off, 0);
67 while((c = get_ch()) != '\r')
68 {
69 switch(c)
70 {
71 case '\b':
72 if(off > 0)
73 {
74 os_strcpy(&buff[off - 1], &buff[off]);
75 --off;
76 }
77 break;
78 case 'A' - '@':
79 off = 0;
80 break;
81 case 'E' - '@':
82 off = os_strlen(buff);
83 break;
84 case 'D' - '@':
85 if(off < os_strlen(buff))
86 os_strcpy(&buff[off], &buff[off + 1]);
87 break;
88 case 'F' - '@':
89 if(off < os_strlen(buff))
90 ++off;
91 break;
92 case 'B' - '@':
93 if(off)
94 --off;
95 break;
96 case 'P' - '@':
97 case 'N' - '@':
98 if(cmd_held)
99 {
100 if(c == 'P' - '@')
101 {
102 if(cmd_count == 0)
103 cmd_count = cmd_held;
104 cmd_count -= 2;
105 while(cmd_count >= 0 && cmd_buff[cmd_count])
106 --cmd_count;
107 ++cmd_count;
108 }
109 else
110 {
111 cmd_count += bytes(&cmd_buff[cmd_count]);
112 if(cmd_count == cmd_held)
113 cmd_count = 0;
114 }
115 off = bytes(&cmd_buff[cmd_count]);
116 os_mcpy(buff, &cmd_buff[cmd_count], min(off, maxlen));
117 buff[maxlen - 1] = '\0';
118 off = os_strlen(buff);
119 }
120 break;
121 case 'U' - '@':
122 off = 0;
123 /* Fall through */
124 case 'K' - '@':
125 buff[off] = '\0';
126 break;
127 default:
128 if(bytes(buff) < maxlen && c >= 32)
129 {
130 os_mcpy(&buff[off + 1], &buff[off], os_strlen(&buff[off]) + 1);
131 buff[off++] = c;
132 }
133 break;
134 }
135 draw_editable(x, (byte *) buff, off, 0);
136 }
137 off = os_strlen(buff);
138 draw_editable(x, (byte *) buff, off, 1);
139 hide_cursor();
140 out_char('\n');
141
142 swap_font_status(&font);
143
144 game_saved = 0;
145
146 /* Store in history */
147
148 if(off && off + 1 < CMD_LIMIT)
149 {
150 int i = 0;
151 while(cmd_held + off - i >= CMD_LIMIT)
152 i += bytes(&cmd_buff[i]);
153 cmd_held -= i;
154 os_mcpy(cmd_buff, &cmd_buff[i], cmd_held);
155 os_strcpy(&cmd_buff[cmd_held], buff);
156 cmd_held += off + 1;
157 }
158 return off;
159 }
160
out_char(word c)161 void out_char(word c)
162 {
163 extern bool newlines_are_significant;
164 extern bool windowing_enabled;
165 extern word current_window;
166 extern word status_height;
167 extern bool enable_screen;
168 extern int linecount;
169 script_char(c);
170 put_char(c);
171 if(enable_screen)
172 {
173 if(c == '\n')
174 {
175 int page = !windowing_enabled || current_window == 0;
176 if(page && newlines_are_significant)
177 {
178 int lose = windowing_enabled ? 0 : status_height;
179 int high = hd_height() - lose - 3;
180 if(linecount++ >= high)
181 {
182 force_update();
183 more();
184 newlines_are_significant = 0;
185 linecount = 0;
186 }
187 }
188 }
189 else
190 {
191 newlines_are_significant = 1;
192 }
193 }
194 }
195
raw_display(const byte * s)196 void raw_display(const byte *s)
197 {
198 start_update();
199 while(*s)
200 put_char(*s++);
201 finish_update();
202 }
203
204 #if 0 /* Used for real-time support */
205 int kbd_hit(void)
206 {
207 return 1;
208 }
209 #endif
210
211