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