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