r/o

Shifted keys. f1208672 parent cc20ca8a

authored by Yuki Izumi

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#include "qb.h"
6
#include "text.h"
7
8
doc_line_t *active_doc;
9
int cursor_x = 0;
10
int cursor_y = 0;
11
int total_lines = 1;
12
int qb_running = 1;
13
14
static SDL_Keycode shift_table[][2] = {
15
{SDLK_QUOTE, SDLK_QUOTEDBL},
16
{SDLK_COMMA, SDLK_LESS},
17
{SDLK_MINUS, SDLK_UNDERSCORE},
18
{SDLK_PERIOD, SDLK_GREATER},
19
{SDLK_SLASH, SDLK_QUESTION},
20
{SDLK_0, SDLK_RIGHTPAREN},
21
{SDLK_1, SDLK_EXCLAIM},
22
{SDLK_2, SDLK_AT},
23
{SDLK_3, SDLK_HASH},
24
{SDLK_4, SDLK_DOLLAR},
25
{SDLK_5, SDLK_PERCENT},
26
{SDLK_6, SDLK_CARET},
27
{SDLK_7, SDLK_AMPERSAND},
28
{SDLK_8, SDLK_ASTERISK},
29
{SDLK_9, SDLK_LEFTPAREN},
30
{SDLK_SEMICOLON, SDLK_COLON},
31
{SDLK_LEFTBRACKET, '{'},
32
{SDLK_BACKSLASH, '|'},
33
{SDLK_RIGHTBRACKET, '}'},
34
{SDLK_BACKQUOTE, '~'},
35
{SDLK_EQUALS, SDLK_PLUS},
36
};
37
38
static doc_line_t *create_doc_line(void) {
39
doc_line_t *d = malloc(sizeof(*d));
40
memset(d, 0, sizeof(*d));
41
d->line = malloc(8);
42
d->allocated = 8;
43
return d;
44
}
45
46
static doc_line_t *get_current_doc_line(void) {
47
doc_line_t *d = active_doc;
48
for (int y = 0; y < cursor_y; ++y) {
49
d = d->next;
50
}
51
return d;
52
}
53
54
static void ensure_available(doc_line_t *d, int required) {
55
int allocated = d->allocated;
56
while (allocated < d->stored + required) {
57
allocated *= 2;
58
}
59
60
if (allocated == d->allocated) {
61
return;
62
}
63
64
char *line = malloc(allocated);
65
memcpy(line, d->line, d->stored);
66
free(d->line);
67
d->line = line;
68
d->allocated = allocated;
69
}
70
71
static void insert_character(doc_line_t *d, int offset, char c) {
72
ensure_available(d, 1);
73
bcopy(d->line + offset, d->line + offset + 1, d->stored - offset);
74
d->line[offset] = c;
75
++d->stored;
76
}
77
78
static char get_character(SDL_Keycode sym, Uint16 mod) {
79
if (sym >= SDLK_a && sym <= SDLK_z) {
80
if (mod & (KMOD_SHIFT | KMOD_CAPS)) {
81
return (char) (sym - ('a' - 'A'));
82
}
83
return (char) sym;
84
}
85
86
if (mod & KMOD_SHIFT) {
87
for (int i = 0; i < sizeof(shift_table); ++i) {
88
if (shift_table[i][0] == sym) {
89
return shift_table[i][1];
90
}
91
}
92
}
93
94
return (char) sym;
95
}
96
97
static int is_printable_key(SDL_Keycode sym) {
98
return sym >= SDLK_SPACE && sym <= SDLK_z;
99
}
100
101
void qb_init(void) {
102
active_doc = create_doc_line();
103
active_doc->line = strdup("10 PRINT \"LOL\"");
104
active_doc->stored = strlen(active_doc->line);
105
active_doc->allocated = active_doc->stored + 1;
106
107
active_doc->next = create_doc_line();
108
active_doc->next->line = strdup("20 GOTO 10");
109
active_doc->next->stored = strlen(active_doc->next->line);
110
active_doc->next->allocated = active_doc->next->stored + 1;
111
112
total_lines = 2;
113
114
qb_render();
115
}
116
117
void qb_keypress(SDL_Keycode sym, Uint16 mod) {
118
if (sym == SDLK_ESCAPE) {
119
qb_running = 0;
120
return;
121
}
122
123
if (sym == SDLK_DOWN && cursor_y < total_lines - 1) {
124
++cursor_y;
125
} else if (sym == SDLK_UP && cursor_y > 0) {
126
--cursor_y;
127
} else if (sym == SDLK_LEFT && cursor_x > 0) {
128
--cursor_x;
129
} else if (sym == SDLK_RIGHT) {
130
++cursor_x;
131
} else if (is_printable_key(sym)) {
132
insert_character(
133
get_current_doc_line(),
134
cursor_x,
135
get_character(sym, mod));
136
++cursor_x;
137
}
138
139
qb_render();
140
text_refresh();
141
}
142
143
void qb_render(void) {
144
for (int i = 0; i < 80 * 25; ++i) {
145
screen[i] = 0x1700;
146
}
147
148
for (int x = 0; x < 80; ++x) {
149
screen[x] = 0x7000;
150
}
151
152
const char *menu_options[] = {
153
"File",
154
"Edit",
155
"View",
156
"Search",
157
"Run",
158
"Debug",
159
"Calls",
160
"Options",
161
NULL,
162
};
163
164
int offset = 2;
165
for (int i = 0; ; ++i) {
166
if (!menu_options[i]) {
167
break;
168
}
169
170
int len = strlen(menu_options[i]);
171
for (int j = 0; j < len; ++j) {
172
screen[0 * 80 + offset + 1 + j] = 0x7000 | (menu_options[i][j]);
173
}
174
175
offset += len + 2;
176
}
177
178
screen[0 * 80 + 74] = 0x7000 + 'H';
179
screen[0 * 80 + 75] = 0x7000 + 'e';
180
screen[0 * 80 + 76] = 0x7000 + 'l';
181
screen[0 * 80 + 77] = 0x7000 + 'p';
182
183
screen[1 * 80 + 0] = 0x17da;
184
for (int x = 1; x < 79; ++x) {
185
screen[1 * 80 + x] = 0x17c4;
186
}
187
188
const char *file = "Untitled";
189
int flen = strlen(file);
190
int start = 40 - flen / 2;
191
screen[1 * 80 + start - 1] = 0x7000;
192
193
int j;
194
for (j = 0; j < flen; ++j) {
195
screen[1 * 80 + start + j] = 0x7000 | file[j];
196
}
197
198
screen[1 * 80 + start + j] = 0x7000;
199
200
screen[1 * 80 + 75] = 0x17b4;
201
screen[1 * 80 + 76] = 0x7112;
202
screen[1 * 80 + 77] = 0x17c3;
203
204
screen[1 * 80 + 79] = 0x17bf;
205
206
for (int y = 2; y < 24; ++y) {
207
screen[y * 80 + 0] = screen[y * 80 + 79] = 0x17b3;
208
for (int x = 1; x < 79; ++x) {
209
screen[y * 80 + x] = 0x1700;
210
}
211
}
212
213
doc_line_t *line = active_doc;
214
for (int y = 0; y < 22 && line; ++y, line = line->next) {
215
for (int x = 0; x < line->stored; ++x) {
216
screen[(y + 2) * 80 + 1 + x] += line->line[x];
217
}
218
}
219
220
screen[2 * 80 + 79] = 0x7018;
221
screen[3 * 80 + 79] = 0x0000;
222
for (int y = 4; y < 22; ++y) {
223
screen[y * 80 + 79] = 0x70b0;
224
}
225
screen[22 * 80 + 79] = 0x7019;
226
227
screen[23 * 80 + 1] = 0x701b;
228
screen[23 * 80 + 2] = 0x0000;
229
for (int x = 3; x < 78; ++x) {
230
screen[23 * 80 + x] = 0x70b0;
231
}
232
screen[23 * 80 + 78] = 0x701a;
233
234
const char *footer[] = {
235
"Shift+F1=Help",
236
"F6=Window",
237
"F2=Subs",
238
"F5=Run",
239
"F8=Step",
240
NULL,
241
};
242
243
for (int x = 0; x < 80; ++x) {
244
screen[24 * 80 + x] = 0x3000;
245
}
246
247
offset = 1;
248
for (int i = 0; ; ++i) {
249
if (!footer[i]) {
250
break;
251
}
252
253
int len = strlen(footer[i]);
254
screen[24 * 80 + offset] += '<';
255
int j;
256
for (j = 0; j < len; ++j) {
257
screen[24 * 80 + offset + 1 + j] += footer[i][j];
258
}
259
screen[24 * 80 + offset + 1 + j] += '>';
260
261
offset += len + 3;
262
}
263
264
screen[24 * 80 + 62] += 0xb3;
265
266
char *counter;
267
asprintf(&counter, "%05d:%03d", cursor_y + 1, cursor_x + 1);
268
int len = strlen(counter);
269
for (int i = 0; i < len; ++i) {
270
screen[24 * 80 + 70 + i] += counter[i];
271
}
272
free(counter);
273
274
screen_cursor_x = cursor_x + 1;
275
screen_cursor_y = cursor_y + 2;
276
}
277
278
/* vim: set sw=4 et: */
279