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
+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+}