Mirai's Miscellaneous Misadventures
M39 / engines / mfb.c
1
2
3
4#include <stdlib.h>
5
6#include <MiniFB.h>
7
8#include <mimimi/engines.h>
9#include <mimimi/assets.h>
10#include <mimimi/behaviors.h>
11#include <mimimi/geometry.h>
12#include <mimimi/chapters.h>
13#include <mimimi/engines/mfb.h>
14#include <mimimi/malloc.h>
15
16static void *mimimi_mfb_texture(void *data, struct mimimi_image *image)
17{
18 (void) data;
19 return image;
20}
21
22static void mimimi_mfb_invalidate(void *data, void *texture)
23{
24 (void) data;
25 (void) texture;
26}
27
28static void mimimi_mfb_stamp(void *data, int x1, int y1, void *texture)
29{
30 static unsigned char rch[] = {0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF};
31 static unsigned char gch[] = {0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF};
32 static unsigned char bch[] = {0x22, 0x55, 0x88, 0xBB, 0xEE};
33
34 struct mimimi_image *image = texture;
35
36 uint32_t *buffer = data;
37
38 int x0 = 0;
39 int y0 = 0;
40
41 if (x1 < 0) x0 = -x1;
42 if (y1 < 0) y0 = -y1;
43
44 int width = image->width;
45 int height = image->height;
46
47 if (width + x1 > 512) width = 512 - x1;
48 if (height + y1 > 256) height = 256 - y1;
49
50 for (int y = y0 ; y < height ; y++)
51 for (int x = x0 ; x < width ; x++)
52 {
53 unsigned char color = image->colors[x + y * image->width];
54 if (color == 0) continue;
55
56 int x2 = x + x1;
57 int y2 = y + y1;
58
59 int offset = x2 + y2 * 512;
60
61 if (color < 0x10)
62 {
63 unsigned char ch = color * 0x11;
64 buffer[offset] = MFB_RGB(ch, ch, ch);
65 }
66 else
67 {
68 color -= 0x10;
69 unsigned char r, g, b;
70 r = rch[(color / 40) % 6];
71 g = gch[(color / 5) % 8];
72 b = bch[(color / 1) % 5];
73
74 buffer[offset] = MFB_RGB(r, g, b);
75 }
76 }
77}
78
79void mimimi_mfb(struct mimimi_chapter *(*start)(struct mimimi_engine *engine))
80{
81 static struct mimimi_size size = {512, 256};
82
83 struct mfb_window *window = mfb_open_ex("mimimi test", size.width, size.height, WF_RESIZABLE);
84 if (window == NULL) exit(1);
85
86 uint32_t *buffer = malloc(size.width * size.height * 4);
87 if (buffer == NULL) exit(1);
88
89 struct mimimi_engine engine;
90 engine.data = buffer;
91 engine.texture = &mimimi_mfb_texture;
92 engine.invalidate = &mimimi_mfb_invalidate;
93 engine.stamp = &mimimi_mfb_stamp;
94 engine.size = &size;
95 engine.allocator = mimimi_malloc;
96 struct mimimi_chapter *chapter = (*start)(&engine);
97 struct mimimi_behavior *behavior = chapter->behavior;
98
99 for (;;)
100 {
101 unsigned char *keys = (void *) mfb_get_key_buffer(window);
102 if (keys[KB_KEY_Q] != 0) break;
103
104 chapter->left = keys[KB_KEY_LEFT];
105 chapter->right = keys[KB_KEY_RIGHT];
106
107 (*behavior->behave)(behavior->data);
108
109 if (mfb_update_ex(window, buffer, size.width, size.height) < 0)
110 break;
111 if (mfb_wait_sync(window) == 0)
112 break;
113 }
114
115 mfb_close(window);
116 (*behavior->finish)(behavior->data);
117 free(buffer);
118}