Mirai's Miscellaneous Misadventures

M17 / engines / mfb.c

// copyright 2022 zamfofex
// license: AGPLv3 or later

#include <stdlib.h>
#include <stddef.h>

#include <MiniFB.h>

#include <mimimi/engines.h>
#include <mimimi/assets.h>

static void mimimi_mfb_stamp(void *opaque, int x0, int y0, struct mimimi_image *image)
{
	uint32_t *buffer = opaque;
	
	static unsigned char xterm[] = {0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF};
	
	for (int y = 0 ; y < image->height ; y++)
	for (int x = 0 ; x < image->width ; x++)
	{
		int x1 = x + x0;
		int y1 = y + y0;
		
		if (x1 < 0) continue;
		if (y1 < 0) continue;
		if (x1 >= mimimi_width) continue;
		if (y1 >= mimimi_height) continue;
		
		int offset = x1 + y1 * mimimi_width;
		
		unsigned char color = image->colors[x + y * image->width];
		if (color == 0) continue;
		
		color -= 16;
		unsigned char r, g, b;
		r = xterm[(color / 36) % 6];
		g = xterm[(color / 6) % 6];
		b = xterm[color % 6];
		
		buffer[offset + 0] = MFB_RGB(r, g, b);
	}
}

void mimimi_mfb(struct mimimi_chapter *chapter)
{
	struct mfb_window *window = mfb_open_ex("Mirai's Miscellaneous Misadventures", mimimi_width, mimimi_height, WF_RESIZABLE);
	if (window == NULL) return;
	
	uint32_t *buffer = malloc(mimimi_width * mimimi_height * 4);
	if (buffer == NULL) return;
	
	struct mimimi_engine engine = {buffer, &mimimi_mfb_stamp};
	struct mimimi_game *game = malloc(mimimi_game_size);
	mimimi_start(game, &engine, chapter);
	
	for (;;)
	{
		for (int y = 0 ; y < mimimi_height ; y++)
		for (int x = 0 ; x < mimimi_width ; x++)
		{
			int offset = x + y * mimimi_width;
			buffer[offset] = MFB_RGB(0xEE, 0xEE, 0xEE);
		}
		
		unsigned char *keys = mfb_get_key_buffer(window);
		struct mimimi_keys input = {keys[KB_KEY_LEFT], keys[KB_KEY_RIGHT]};
		
		if (keys[KB_KEY_Q]) break;
		
		mimimi_step(game, input);
		
		if(mfb_update_ex(window, buffer, mimimi_width, mimimi_height) < 0) 
			break;
	}
}