1// i got to eventually clean up this file a bit i feel like its very janky but i suppose i can worry about that later
2
3#include <stdio.h>
4#include <string.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <OS.h>
8#include "interpreter.h"
9#include "cottonwindow.h"
10#include "eiki.h"
11
12// maximum length of a .cot file line
13#define MAX_LINE 256
14
15
16// da string stuff
17
18static void strip_newline(char *s)
19{
20 s[strcspn(s, "\r\n")] = 0;
21}
22
23static char *get_arg(char *line)
24{
25 char *space = strchr(line, ' ');
26
27 if (space != NULL)
28 {
29 return space + 1;
30 }
31
32 else
33 {
34 return NULL;
35 }
36}
37
38static char *strip_quotes(char *s)
39{
40 if (s[0] == '"')
41 {
42 char *end = strrchr(s, '"');
43
44 if (end == NULL)
45 {
46 fprintf(stderr, "looks like you forgot a quote at the end xP\n");
47 return s;
48 }
49
50 *end = '\0';
51 return s + 1;
52 }
53
54 return s;
55}
56
57
58// da graphics stuff
59
60static void draw_pixel(Cotton *cotton, int x, int y)
61{
62 cotton->video[y * VIDEO_WIDTH + x] = cotton->c_cottolette;
63}
64
65static void draw_char(Cotton *cotton, char c, int x, int y)
66{
67 for (int row = 0; row < FONT_HEIGHT; row++)
68 {
69 uint8_t bits = EIKI_FONT[(uint8_t)c][row];
70
71 for (int col = 0; col < FONT_WIDTH; col++)
72 {
73
74 if (bits & (1 << col))
75 {
76 draw_pixel(cotton, x + col, y + row);
77 }
78 }
79
80 }
81}
82
83
84// da commands
85
86static void cmd_print(Cotton *cotton, CottonWindow *cw, char *arg)
87{
88 if (!arg)
89 return;
90
91 char *text = strip_quotes(arg);
92
93 printf("%s\n", text);
94
95 for (int i = 0; text[i] != '\0'; i++)
96 {
97 if (text[i] == '\n')
98 {
99 cotton->cursor_x = 0;
100 cotton->cursor_y += FONT_HEIGHT + 4;
101 continue;
102 }
103
104 draw_char(cotton, text[i], cotton->cursor_x, cotton->cursor_y);
105 cotton->cursor_x += FONT_WIDTH + 2;
106
107 if (cotton->cursor_x + FONT_WIDTH + 2 >= VIDEO_WIDTH)
108 {
109 cotton->cursor_x = 0;
110 cotton->cursor_y += FONT_HEIGHT + 4;
111 }
112 }
113
114 cotton->cursor_x = 0;
115 cotton->cursor_y += FONT_HEIGHT + 4;
116
117 cottonwindow_update(cw, cotton->video, sizeof(cotton->video[0]) * VIDEO_WIDTH);
118
119}
120
121static void cmd_wait(Cotton *cotton, char *arg)
122{
123 if (!arg)
124 return;
125
126 int seconds = atoi(arg);
127
128 cotton->ticktock = system_time() / 100 + (seconds * 1000);
129}
130
131static void cmd_kill(void)
132{
133 printf("[cotton stopped]\n");
134 exit(0);
135}
136
137static void cmd_clear(Cotton *cotton, CottonWindow *cw)
138{
139 for (int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++)
140 {
141 cotton->video[i] = 0;
142 }
143
144 cotton->cursor_x = 0;
145 cotton->cursor_y = 0;
146
147 cottonwindow_update(cw, cotton->video, sizeof(cotton->video[0]) * VIDEO_WIDTH);
148}
149
150static void cmd_color(Cotton *cotton, char *arg)
151{
152 if (!arg) return;
153
154 if (strcmp(arg, "black") == 0)
155 cotton->c_cottolette = COTTOLETTE[0];
156
157 else if (strcmp(arg, "white") == 0)
158 cotton->c_cottolette = COTTOLETTE[1];
159
160 else if (strcmp(arg, "rey") == 0)
161 cotton->c_cottolette = COTTOLETTE[2];
162
163 else if (strcmp(arg, "wist") == 0)
164 cotton->c_cottolette = COTTOLETTE[3];
165
166 else if (strcmp(arg, "wink") == 0)
167 cotton->c_cottolette = COTTOLETTE[4];
168
169 else if (strcmp(arg, "laven") == 0)
170 cotton->c_cottolette = COTTOLETTE[5];
171
172 else if (strcmp(arg, "geen") == 0)
173 cotton->c_cottolette = COTTOLETTE[6];
174
175 else
176 fprintf(stderr, "cotton doesn't know the color \"%s\" sorry,, :(\n", arg);
177}
178
179static void cmd_input(CottonWindow *cw, char *arg)
180{
181 (void)cw;
182 (void)arg;
183
184 // will work on this for v0.2 or whenever it is that i add variables
185}
186
187static void cmd_unknown(const char *cmd)
188{
189 fprintf(stderr, "cotton doesn't know what \"%s\" means, care to type that out again? :<\n", cmd);
190}
191
192
193// da interpreter loop
194
195void cotton_interpret(Cotton *cotton, CottonWindow *cw, FILE *file)
196{
197 char line[MAX_LINE];
198
199 // this reads the file one line at a time until we get to da end of da file
200 if (!fgets(line, sizeof(line), file))
201 return;
202
203 strip_newline(line);
204
205 // cot shall use # comments like C because C is cool and i love C so bwaaa
206 if (line[0] == '\0' || line[0] == '#')
207 return;
208
209
210 char line_copy[MAX_LINE];
211
212 strncpy(line_copy, line, MAX_LINE - 1);
213 line_copy[MAX_LINE - 1] = '\0';
214
215
216 char *cmd = strtok(line_copy, " ");
217
218 if (!cmd)
219 return;
220
221
222 // RELEASE THE KRAKE- I MEAN, RELEASE THE GREAT WALL OF COMMANDS !!!
223 // could i format this better? maybe,, but but i'd say this is readable and i think readability is gud so i will keep it nice and green,,, green!! :D
224 char *arg = get_arg(line);
225
226
227 if (strcmp(cmd, "print") == 0)
228 {
229 cmd_print(cotton, cw, arg);
230 }
231
232 else if (strcmp(cmd, "clear") == 0)
233 {
234 cmd_clear(cotton, cw);
235 }
236
237 else if (strcmp(cmd, "color") == 0)
238 {
239 cmd_color(cotton, arg);
240 }
241
242 else if (strcmp(cmd, "wait") == 0)
243 {
244 cmd_wait(cotton, arg);
245 }
246
247 else if (strcmp(cmd, "input") == 0)
248 {
249 cmd_input(cw, arg);
250 }
251
252 else if (strcmp(cmd, "kill") == 0)
253 {
254 cmd_kill();
255 }
256
257 else
258 {
259 cmd_unknown(cmd);
260 }
261}