commit 7890268
chld
·
2026-07-21 03:09:38 +0000 UTC
parent 7890268
init
10 files changed,
+759,
-0
+6,
-0
1@@ -0,0 +1,6 @@
2+*.out
3+*.core
4+*.o
5+*.so
6+*.a
7+cotton
A
makefile
+5,
-0
1@@ -0,0 +1,5 @@
2+SRC=cotton
3+LIB=`pkg-config --libs sdl2` -lbe
4+
5+${SRC}:
6+ cc src/*.c ${LIB} -o ${SRC}
+12,
-0
1@@ -0,0 +1,12 @@
2+#include "cotton.h"
3+#include <string.h>
4+#include <time.h>
5+#include <stdlib.h>
6+
7+void cotton_init(Cotton *c)
8+{
9+ memset(c, 0, sizeof(Cotton));
10+
11+ srand((unsigned int)time(NULL));
12+
13+}
+25,
-0
1@@ -0,0 +1,25 @@
2+#ifndef COTTON_H
3+#define COTTON_H
4+
5+#include <stdint.h>
6+
7+#define MEMORY_SIZE (1024 * 1024)
8+#define VIDEO_WIDTH 200
9+#define VIDEO_HEIGHT 125
10+
11+typedef struct
12+{
13+ uint8_t memory[MEMORY_SIZE];
14+ uint32_t video[VIDEO_WIDTH * VIDEO_HEIGHT];
15+
16+ // i cant come up with a better name that gets straight to the point than "cursor" so ig it will stay this way for now,,
17+ int cursor_x;
18+ int cursor_y;
19+
20+ uint32_t ticktock;
21+
22+} Cotton;
23+
24+void cotton_init(Cotton *c);
25+
26+#endif
+81,
-0
1@@ -0,0 +1,81 @@
2+#include "cottonwindow.h"
3+#include <stdio.h>
4+
5+int cottonwindow_init(CottonWindow *cw, const char *title, int window_w, int window_h, int texture_w, int texture_h)
6+{
7+ SDL_Init(SDL_INIT_VIDEO);
8+
9+ if (SDL_Init(SDL_INIT_VIDEO) != 0)
10+ {
11+ fprintf(stderr, "cotton couldn't start SDL :( : %s\n", SDL_GetError());
12+ return 0;
13+ }
14+
15+ cw->window = SDL_CreateWindow(title, 0, 0, window_w, window_h, SDL_WINDOW_SHOWN);
16+ if (!cw->window)
17+ {
18+ fprintf(stderr, "cotton couldn't create a window :( : %s\n", SDL_GetError());
19+ return 0;
20+ }
21+
22+ cw->renderer = SDL_CreateRenderer(cw->window, -1, 0);
23+ if (!cw->renderer)
24+ {
25+ fprintf(stderr, "cotton couldn't render this :( : %s\n", SDL_GetError());
26+ return 0;
27+ }
28+
29+ cw->texture = SDL_CreateTexture(cw->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, texture_w, texture_h);
30+ if (!cw->texture)
31+ {
32+ fprintf(stderr, "cotton couldn't apply textures :( : %s\n", SDL_GetError());
33+ return 0;
34+ }
35+
36+ return 1;
37+}
38+
39+void cottonwindow_update(CottonWindow *cw, const void *buffer, int pitch)
40+{
41+ SDL_UpdateTexture(cw->texture, NULL, buffer, pitch);
42+ SDL_RenderClear(cw->renderer);
43+ SDL_RenderCopy(cw->renderer, cw->texture, NULL, NULL);
44+ SDL_RenderPresent(cw->renderer);
45+}
46+
47+int cottonwindow_process_input(CottonWindow *cw, uint8_t *keys)
48+{
49+ (void)cw;
50+ (void)keys;
51+ int quit = 0;
52+ SDL_Event event;
53+
54+ while (SDL_PollEvent(&event))
55+ {
56+ switch (event.type)
57+ {
58+ case SDL_QUIT:
59+ {
60+ quit = 1;
61+ break;
62+ }
63+
64+ case SDL_KEYDOWN:
65+ {
66+ if (event.key.keysym.sym == SDLK_ESCAPE)
67+ quit = 1;
68+ break;
69+ }
70+ }
71+ }
72+
73+ return quit;
74+}
75+
76+void cottonwindow_destroy(CottonWindow *cw)
77+{
78+ SDL_DestroyTexture(cw->texture);
79+ SDL_DestroyRenderer(cw->renderer);
80+ SDL_DestroyWindow(cw->window);
81+ SDL_Quit();
82+}
+20,
-0
1@@ -0,0 +1,20 @@
2+#ifndef COTTONWINDOW_H
3+#define COTTONWINDOW_H
4+
5+#include <SDL2/SDL.h>
6+#include <stdint.h>
7+
8+typedef struct
9+{
10+ SDL_Window *window;
11+ SDL_Renderer *renderer;
12+ SDL_Texture *texture;
13+
14+} CottonWindow;
15+
16+int cottonwindow_init(CottonWindow *cw, const char *title, int window_w, int window_h, int texture_w, int texture_h);
17+void cottonwindow_update(CottonWindow *cw, const void *buffer, int pitch);
18+int cottonwindow_process_input(CottonWindow *cw, uint8_t *keys);
19+void cottonwindow_destroy(CottonWindow *cw);
20+
21+#endif
+317,
-0
1@@ -0,0 +1,317 @@
2+// I might refactor some of these letters and characters at some point but but for now this should be a-okay :D
3+// Atleast i think these are readable for now so that's good enough x3
4+
5+#ifndef EIKI_H
6+#define EIKI_H
7+
8+#include <stdint.h>
9+
10+static const uint8_t EIKI_FONT[256][5] = {
11+
12+ [' '] = {
13+ 0b00000000,
14+ 0b00000000,
15+ 0b00000000,
16+ 0b00000000,
17+ 0b00000000,
18+ },
19+
20+ ['A'] = {
21+ 0b00001110,
22+ 0b00010001,
23+ 0b00011111,
24+ 0b00010001,
25+ 0b00010001,
26+ },
27+
28+ ['B'] = {
29+ 0b00001111,
30+ 0b00010001,
31+ 0b00001111,
32+ 0b00010001,
33+ 0b00001111,
34+ },
35+
36+ ['C'] = {
37+ 0b00011111,
38+ 0b00000001,
39+ 0b00000001,
40+ 0b00000001,
41+ 0b00011111,
42+ },
43+
44+ ['D'] = {
45+ 0b00001111,
46+ 0b00010001,
47+ 0b00010001,
48+ 0b00010001,
49+ 0b00001111,
50+ },
51+
52+ ['E'] = {
53+ 0b00011111,
54+ 0b00000001,
55+ 0b00011111,
56+ 0b00000001,
57+ 0b00011111,
58+ },
59+
60+ ['F'] = {
61+ 0b00011111,
62+ 0b00000001,
63+ 0b00011111,
64+ 0b00000001,
65+ 0b00000001,
66+ },
67+
68+ ['G'] = {
69+ 0b00011111,
70+ 0b00000001,
71+ 0b00011001,
72+ 0b00010001,
73+ 0b00011111,
74+ },
75+
76+ ['H'] = {
77+ 0b00010001,
78+ 0b00010001,
79+ 0b00011111,
80+ 0b00010001,
81+ 0b00010001,
82+ },
83+
84+ ['I'] = {
85+ 0b00011111,
86+ 0b00000100,
87+ 0b00000100,
88+ 0b00000100,
89+ 0b00011111,
90+ },
91+
92+ ['J'] = {
93+ 0b00011100,
94+ 0b00010000,
95+ 0b00010000,
96+ 0b00010011,
97+ 0b00011110,
98+ },
99+
100+ ['K'] = {
101+ 0b00010001,
102+ 0b00011001,
103+ 0b00000111,
104+ 0b00010001,
105+ 0b00010001,
106+ },
107+
108+ ['L'] = {
109+ 0b00000001,
110+ 0b00000001,
111+ 0b00000001,
112+ 0b00010001,
113+ 0b00011111,
114+ },
115+
116+ ['M'] = {
117+ 0b00011011,
118+ 0b00011111,
119+ 0b00010101,
120+ 0b00010001,
121+ 0b00010001,
122+ },
123+
124+ ['N'] = {
125+ 0b00010001,
126+ 0b00010011,
127+ 0b00010101,
128+ 0b00011001,
129+ 0b00010001,
130+ },
131+
132+ ['O'] = {
133+ 0b00011111,
134+ 0b00010001,
135+ 0b00010001,
136+ 0b00010001,
137+ 0b00011111,
138+ },
139+
140+ ['P'] = {
141+ 0b00011111,
142+ 0b00010001,
143+ 0b00011111,
144+ 0b00000001,
145+ 0b00000001,
146+ },
147+
148+ ['Q'] = {
149+ 0b00011111,
150+ 0b00010001,
151+ 0b00010001,
152+ 0b00011001,
153+ 0b00011111,
154+ },
155+
156+ ['R'] = {
157+ 0b00011111,
158+ 0b00010001,
159+ 0b00011111,
160+ 0b00001001,
161+ 0b00010001,
162+ },
163+
164+ ['S'] = {
165+ 0b00011111,
166+ 0b00000001,
167+ 0b00011111,
168+ 0b00010000,
169+ 0b00011111,
170+ },
171+
172+ ['T'] = {
173+ 0b00011111,
174+ 0b00000100,
175+ 0b00000100,
176+ 0b00000100,
177+ 0b00000100,
178+ },
179+
180+ ['U'] = {
181+ 0b00010001,
182+ 0b00010001,
183+ 0b00010001,
184+ 0b00010001,
185+ 0b00011111,
186+ },
187+
188+ ['V'] = {
189+ 0b00010001,
190+ 0b00010001,
191+ 0b00011011,
192+ 0b00001010,
193+ 0b00000100,
194+ },
195+
196+ ['W'] = {
197+ 0b00010001,
198+ 0b00010001,
199+ 0b00010101,
200+ 0b00011011,
201+ 0b00010001,
202+ },
203+
204+ ['X'] = {
205+ 0b00010001,
206+ 0b00001010,
207+ 0b00000100,
208+ 0b00001010,
209+ 0b00010001,
210+ },
211+
212+ ['Y'] = {
213+ 0b00010001,
214+ 0b00010001,
215+ 0b00001010,
216+ 0b00000100,
217+ 0b00000100,
218+ },
219+
220+ ['Z'] = {
221+ 0b00011111,
222+ 0b00010001,
223+ 0b00000100,
224+ 0b00010010,
225+ 0b00011111,
226+ },
227+
228+ ['0'] = {
229+ 0b00001110,
230+ 0b00010001,
231+ 0b00010001,
232+ 0b00010001,
233+ 0b00001110,
234+ },
235+
236+ ['1'] = {
237+ 0b00000100,
238+ 0b00001100,
239+ 0b00000100,
240+ 0b00000100,
241+ 0b00001110,
242+ },
243+
244+ ['2'] = {
245+ 0b00001110,
246+ 0b00010001,
247+ 0b00000010,
248+ 0b00000100,
249+ 0b00011111,
250+ },
251+
252+ ['3'] = {
253+ 0b00011111,
254+ 0b00010001,
255+ 0b00011100,
256+ 0b00010001,
257+ 0b00011111,
258+ },
259+
260+ ['4'] = {
261+ 0b00010010,
262+ 0b00010010,
263+ 0b00011111,
264+ 0b00000010,
265+ 0b00000010,
266+ },
267+
268+ ['5'] = {
269+ 0b00011111,
270+ 0b00010000,
271+ 0b00011110,
272+ 0b00000001,
273+ 0b00011110,
274+ },
275+
276+ ['6'] = {
277+ 0b00001110,
278+ 0b00010000,
279+ 0b00011110,
280+ 0b00010001,
281+ 0b00001110,
282+ },
283+
284+ ['7'] = {
285+ 0b00011111,
286+ 0b00000001,
287+ 0b00000010,
288+ 0b00000100,
289+ 0b00000100,
290+ },
291+
292+ ['8'] = {
293+ 0b00001110,
294+ 0b00010001,
295+ 0b00001110,
296+ 0b00010001,
297+ 0b00001110,
298+ },
299+
300+ ['9'] = {
301+ 0b00001110,
302+ 0b00010001,
303+ 0b00001111,
304+ 0b00000001,
305+ 0b00001110,
306+ },
307+
308+ [':'] = {
309+ 0b00000000,
310+ 0b00000100,
311+ 0b00000000,
312+ 0b00000100,
313+ 0b00000000,
314+ },
315+
316+};
317+
318+#endif
+236,
-0
1@@ -0,0 +1,236 @@
2+// 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
3+
4+#include <stdio.h>
5+#include <string.h>
6+#include <stdlib.h>
7+#include <unistd.h>
8+#include <SDL2/SDL.h>
9+#include "interpreter.h"
10+#include "cottonwindow.h"
11+#include "eiki.h"
12+
13+// maximum length of a .cot file line
14+#define MAX_LINE 256
15+
16+
17+// da string stuff
18+
19+static void strip_newline(char *s)
20+{
21+ s[strcspn(s, "\r\n")] = 0;
22+}
23+
24+static char *get_arg(char *line)
25+{
26+ char *space = strchr(line, ' ');
27+
28+ if (space != NULL)
29+ {
30+ return space + 1;
31+ }
32+
33+ else
34+ {
35+ return NULL;
36+ }
37+}
38+
39+static char *strip_quotes(char *s)
40+{
41+ if (s[0] == '"')
42+ {
43+ char *end = strrchr(s, '"');
44+
45+ if (end == NULL)
46+ {
47+ fprintf(stderr, "looks like you forgot a quote at the end xP\n");
48+ return s;
49+ }
50+
51+ *end = '\0';
52+ return s + 1;
53+ }
54+
55+ return s;
56+}
57+
58+
59+// da graphics stuff
60+
61+static void draw_pixel(Cotton *cotton, int x, int y, uint32_t color)
62+{
63+ cotton->video[y * VIDEO_WIDTH + x] = color;
64+}
65+
66+static void draw_char(Cotton *cotton, char c, int x, int y)
67+{
68+ for (int row = 0; row < 5; row++)
69+ {
70+ uint8_t bits = EIKI_FONT[(uint8_t)c][row];
71+
72+ for (int col = 0; col < 5; col++)
73+ {
74+
75+ if (bits & (1 << col))
76+ {
77+ draw_pixel(cotton, x + col, y + row, 0xffffffff);
78+ }
79+ }
80+
81+ }
82+}
83+
84+
85+// da commands
86+
87+static void cmd_print(Cotton *cotton, CottonWindow *cw, char *arg)
88+{
89+ (void)cw;
90+
91+ if (!arg)
92+ return;
93+
94+ char *text = strip_quotes(arg);
95+
96+ printf("%s\n", text);
97+
98+ for (int i = 0; text[i] != '\0'; i++)
99+ {
100+ // when the limit of a line is reached we go down one line,, pmo when it just gluedtogehterlikethisacrosslinesaaaaaa
101+ if (text[i] == '\n')
102+ {
103+ cotton->cursor_x = 0;
104+ cotton->cursor_y += 6;
105+ continue;
106+ }
107+
108+ draw_char(cotton, text[i], cotton->cursor_x, cotton->cursor_y);
109+ cotton->cursor_x += 6;
110+
111+ // those who wrap
112+ if (cotton->cursor_x + 6 >= VIDEO_WIDTH)
113+ {
114+ cotton->cursor_x = 0;
115+ cotton->cursor_y += 6;
116+ }
117+ }
118+
119+ cotton->cursor_x = 0;
120+ cotton->cursor_y += 6;
121+
122+}
123+
124+static void cmd_wait(Cotton *cotton, char *arg)
125+{
126+ if (!arg)
127+ return;
128+
129+ int seconds = atoi(arg);
130+
131+ cotton->ticktock = SDL_GetTicks() + (seconds * 1000);
132+}
133+
134+static void cmd_kill(void)
135+{
136+ printf("[cotton stopped]\n");
137+ exit(0);
138+}
139+
140+static void cmd_clear(CottonWindow *cw)
141+{
142+ (void)cw;
143+
144+ // will work on this for v0.2
145+}
146+
147+static void cmd_color(CottonWindow *cw, char *arg)
148+{
149+ (void)cw;
150+ (void)arg;
151+
152+ // will work on this for v0.2
153+}
154+
155+static void cmd_input(CottonWindow *cw, char *arg)
156+{
157+ (void)cw;
158+ (void)arg;
159+
160+ // will work on this for v0.2 or whenever it is that i add variables
161+}
162+
163+static void cmd_unknown(const char *cmd)
164+{
165+ fprintf(stderr, "cotton doesn't know what \"%s\" means, care to type that out again? :<\n", cmd);
166+}
167+
168+
169+// da interpreter loop
170+
171+void cotton_interpret(Cotton *cotton, CottonWindow *cw, FILE *file)
172+{
173+ char line[MAX_LINE];
174+
175+ // this reads the file one line at a time until we get to da end of da file
176+ if (!fgets(line, sizeof(line), file))
177+ return;
178+
179+ strip_newline(line);
180+
181+ // cot shall use # comments like C because C is cool and i love C so bwaaa
182+ if (line[0] == '\0' || line[0] == '#')
183+ return;
184+
185+
186+ char line_copy[MAX_LINE];
187+
188+ strncpy(line_copy, line, MAX_LINE - 1);
189+ line_copy[MAX_LINE - 1] = '\0';
190+
191+
192+ char *cmd = strtok(line_copy, " ");
193+
194+ if (!cmd)
195+ return;
196+
197+
198+ // RELEASE THE KRAKE- I MEAN, RELEASE THE GREAT WALL OF COMMANDS !!!
199+ // 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
200+ char *arg = get_arg(line);
201+
202+
203+ if (strcmp(cmd, "print") == 0)
204+ {
205+ cmd_print(cotton, cw, arg);
206+ }
207+
208+ else if (strcmp(cmd, "clear") == 0)
209+ {
210+ cmd_clear(cw);
211+ }
212+
213+ else if (strcmp(cmd, "color") == 0)
214+ {
215+ cmd_color(cw, arg);
216+ }
217+
218+ else if (strcmp(cmd, "wait") == 0)
219+ {
220+ cmd_wait(cotton, arg);
221+ }
222+
223+ else if (strcmp(cmd, "input") == 0)
224+ {
225+ cmd_input(cw, arg);
226+ }
227+
228+ else if (strcmp(cmd, "kill") == 0)
229+ {
230+ cmd_kill();
231+ }
232+
233+ else
234+ {
235+ cmd_unknown(cmd);
236+ }
237+}
+10,
-0
1@@ -0,0 +1,10 @@
2+#ifndef INTERPRETER_H
3+#define INTERPRETER_H
4+
5+#include "cotton.h"
6+#include "cottonwindow.h"
7+#include <stdio.h>
8+
9+void cotton_interpret(Cotton *cotton, CottonWindow *cw, FILE *file);
10+
11+#endif
+47,
-0
1@@ -0,0 +1,47 @@
2+#include <stdio.h>
3+#include "cotton.h"
4+#include "cottonwindow.h"
5+#include "interpreter.h"
6+
7+int main(int argc, char **argv)
8+{
9+ if (argc != 2)
10+ {
11+ fprintf(stderr, "usage: cotton <file.cot>\n");
12+ return 1;
13+ }
14+
15+ CottonWindow cw;
16+
17+ if (!cottonwindow_init(&cw, "cotton", VIDEO_WIDTH * 4, VIDEO_HEIGHT * 4, VIDEO_WIDTH, VIDEO_HEIGHT))
18+ return 1;
19+
20+ Cotton cotton;
21+ cotton_init(&cotton);
22+
23+ FILE *file = fopen(argv[1], "r");
24+ if (!file)
25+ {
26+ fprintf(stderr, "cotton couldn't open \"%s\" :(\n", argv[1]);
27+ return 1;
28+ }
29+
30+ int pitch = sizeof(cotton.video[0]) * VIDEO_WIDTH;
31+ int quit = 0;
32+
33+ while (!quit)
34+ {
35+ quit = cottonwindow_process_input(&cw, NULL);
36+
37+ if (SDL_GetTicks() >= cotton.ticktock)
38+ {
39+ cotton_interpret(&cotton, &cw, file);
40+ }
41+
42+ cottonwindow_update(&cw, cotton.video, pitch);
43+ }
44+
45+ fclose(file);
46+ cottonwindow_destroy(&cw);
47+ return 0;
48+}