Mirai's Miscellaneous Misadventures

M20 / engines / sdl2.c

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

// todo: this is currently not working, fix it

#include <stdlib.h>
#include <SDL2/SDL.h>

#include "../mimimi.h"

struct mimimi_sdl2
{
	SDL_Renderer *renderer;
	struct mimimi_image *images;
	SDL_Texture **textures;
};

static void mimimi_sdl2_stamp(void *opaque, int x, int y, struct mimimi_image *image)
{
	struct mimimi_sdl2 *data = opaque;
	SDL_Renderer *renderer = data->renderer;
	
	SDL_Rect rect;
	rect.x = x;
	rect.y = y;
	rect.w = image->width;
	rect.h = image->height;
	
	int i = image - data->images;
	
	SDL_RenderCopy(renderer, data->textures[i], NULL, &rect);
}

int main(int argc, char **argv)
{
	atexit(&SDL_Quit);
	
	SDL_Init(SDL_INIT_VIDEO);
	
	SDL_Window *window;
	SDL_Renderer *renderer;
	
	SDL_CreateWindowAndRenderer(mimimi_width, mimimi_height, 0, &window, &renderer);
	SDL_RenderSetLogicalSize(renderer, mimimi_width, mimimi_height);
	SDL_SetWindowTitle(window, "Mirai's Miscellaneous Misadventures");
	
	struct mimimi_image *images = mimimi_assets();
	struct mimimi_image *image = images;
	int image_count = 0;
	
	while (image->width != 0)
	{
		image_count++;
		image++;
	}
	image = images;
	
	SDL_Texture **textures = malloc(image_count * sizeof *textures);
	
	for (int i = 0 ; image->width != 0 ; i++)
	{
		SDL_Surface *surface = SDL_CreateRGBSurface(0, image->width, image->height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
		for (int x = 0 ; x < image->width ; x++)
		for (int y = 0 ; y < image->height ; y++)
		{
			static unsigned char xterm[] = {0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF};
			
			Uint32 o = x * 4 + y * surface->pitch;
			Uint32 *pixel = (Uint32 *) ((char *) surface->pixels + o);
			
			Uint32 r, g, b, a;
			unsigned char color = image->colors[x + y * image->width];
			if (color == 0)
			{
				r = 0x00;
				g = 0x00;
				b = 0x00;
				a = 0x00;
			}
			else
			{
				color -= 16;
				r = xterm[(color / 36) % 6];
				g = xterm[(color / 6) % 6];
				b = xterm[color % 6];
				a = 0xFF;
			}
			
			*pixel = (r << 24) | (g << 16) | (b << 8) | (a << 0);
		}
		
		textures[i] = SDL_CreateTextureFromSurface(renderer, surface);
		
		SDL_FreeSurface(surface);
		image++;
	}
	
	struct mimimi_sdl2 data = {renderer, images, textures};
	
	struct mimimi_engine engine = {&data, &mimimi_sdl2_stamp};
	struct mimimi_game *game = malloc(mimimi_game_size);
	mimimi_start(game, &engine, mimimi_test);
	
	Uint32 past = SDL_GetTicks();
	
	for (;;)
	{
		Uint32 current = SDL_GetTicks();
		Uint32 delay = current - past;
		past = current;
		if (delay < 33) SDL_Delay(33 - delay);
		
		SDL_Event event;
		while (SDL_PollEvent(&event))
		{
			if (event.type == SDL_QUIT) return 0;
			
			if (event.type == SDL_KEYDOWN)
			{
				switch (event.key.keysym.sym)
				{
					default: continue;
					case SDLK_q: return 0;
				}
			}
		}
		
		struct mimimi_keys keys = {0, 0};
		
		unsigned char *keyboard = SDL_GetKeyboardState(NULL);
		if (keyboard[SDL_SCANCODE_LEFT]) keys.left = 1;
		if (keyboard[SDL_SCANCODE_RIGHT]) keys.right = 1;
		
		SDL_Rect rect = {0, 0, mimimi_width, mimimi_height};
		SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
		SDL_RenderClear(renderer);
		SDL_SetRenderDrawColor(renderer, 0xEE, 0xEE, 0xEE, 0xFF);
		SDL_RenderFillRect(renderer, &rect);
		mimimi_step(game, keys);
		SDL_RenderPresent(renderer);
	}
}