Mirai's Miscellaneous Misadventures

M24 / engines / mfb.c

1// copyright 2022 zamfofex
2// license: AGPLv3 or later
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
14#include <mimimi/engines/mfb.h>
15
16static struct mimimi_size mimimi_mfb_size = {512, 256};
17
18static void mimimi_mfb_stamp(void *data, int x0, int y0, struct mimimi_image *image)
19{
20	static unsigned char rch[] = {0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF};
21	static unsigned char gch[] = {0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF};
22	static unsigned char bch[] = {0x22, 0x55, 0x88, 0xBB, 0xEE};
23	
24	uint32_t *buffer = data;
25	
26	for (int y = 0 ; y < image->height ; y++)
27	for (int x = 0 ; x < image->width ; x++)
28	{
29		int x1 = x + x0;
30		int y1 = y + y0;
31		
32		if (x1 < 0) continue;
33		if (y1 < 0) continue;
34		if (x1 >= mimimi_mfb_size.width) continue;
35		if (y1 >= mimimi_mfb_size.height) continue;
36		
37		int offset = x1 + y1 * mimimi_mfb_size.width;
38		
39		unsigned char color = image->colors[x + y * image->width];
40		if (color == 0) continue;
41		
42		if (color < 0x10)
43		{
44			unsigned char ch = color * 0x11;
45			buffer[offset] = MFB_RGB(ch, ch, ch);
46		}
47		else
48		{
49			color -= 0x10;
50			unsigned char r, g, b;
51			r = rch[(color / 40) % 6];
52			g = gch[(color / 5) % 8];
53			b = bch[(color / 1) % 5];
54			
55			buffer[offset] = MFB_RGB(r, g, b);
56		}
57	}
58}
59
60void mimimi_mfb(struct mimimi_chapter *chapter)
61{
62	struct mfb_window *window = mfb_open_ex("Mirai's Miscellaneous Misadventures", mimimi_mfb_size.width, mimimi_mfb_size.height, WF_RESIZABLE);
63	if (window == NULL) exit(1);
64	
65	uint32_t *buffer = malloc(mimimi_mfb_size.width * mimimi_mfb_size.height * 4);
66	if (buffer == NULL) exit(1);
67	
68	chapter->engine->data = buffer;
69	chapter->engine->stamp = &mimimi_mfb_stamp;
70	chapter->engine->size = &mimimi_mfb_size;
71	
72	struct mimimi_behavior *behavior = chapter->behavior;
73	
74	for (;;)
75	{
76		unsigned char *keys = mfb_get_key_buffer(window);
77		if (keys[KB_KEY_Q]) break;
78		
79		chapter->left = keys[KB_KEY_LEFT];
80		chapter->right = keys[KB_KEY_RIGHT];
81		
82		(*behavior->behave)(behavior->data);
83		
84		if(mfb_update_ex(window, buffer, mimimi_mfb_size.width, mimimi_mfb_size.height) < 0) 
85			break;
86	}
87	
88	mfb_close(window);
89	(*behavior->finish)(behavior->data);
90	free(buffer);
91}