Mirai's Miscellaneous Misadventures

M52 / engines / sdl.c

1/* license: AGPLv3 or later */
2/* copyright 2024 zamfofex */
3
4#include <stdlib.h>
5#include <SDL2/SDL.h>
6#include "../mimimi.h"
7
8static SDL_Texture *mimimi_sdl2_texture(SDL_Renderer *renderer, struct mimimi_image *image)
9{
10	static unsigned char rch[] = {0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF};
11	static unsigned char gch[] = {0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF};
12	static unsigned char bch[] = {0x22, 0x55, 0x88, 0xBB, 0xEE};
13	
14	int x, y;
15	unsigned char color;
16	SDL_Texture *texture;
17	SDL_Surface *surface;
18	Uint32 offset;
19	Uint32 *pixel;
20	Uint32 r, g, b, a;
21	
22	surface = SDL_CreateRGBSurface(0, image->width, image->height, 32, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000L);
23	for (x = 0 ; x < image->width ; x++)
24	for (y = 0 ; y < image->height ; y++)
25	{
26		offset = x * 4 + y * surface->pitch;
27		pixel = (Uint32 *) ((char *) surface->pixels + offset);
28		
29		color = image->colors[x + y * image->width];
30		if (color == 0)
31		{
32			*pixel = 0;
33		}
34		else if (color < 0x10)
35		{
36			a = color * 0x11;
37			*pixel = (0xFFL << 24) | (a << 16) | (a << 8) | (a << 0);
38		}
39		else
40		{
41			color -= 0x10;
42			r = rch[(color / 40) % 6];
43			g = gch[(color / 5) % 8];
44			b = bch[(color / 1) % 5];
45			a = 0xFF;
46			*pixel = (a << 24) | (r << 16) | (g << 8) | (b << 0);
47		}
48	}
49	
50	texture = SDL_CreateTextureFromSurface(renderer, surface);
51	
52	SDL_FreeSurface(surface);
53	
54	return texture;
55}
56
57void mimimi_main(void (*tick)(void *data, struct mimimi_output *output, struct mimimi_input *input), void *data)
58{
59	struct mimimi_input input;
60	struct mimimi_output output;
61	SDL_Window *window;
62	SDL_Renderer *renderer;
63	Uint32 past, current, delay;
64	SDL_Event event;
65	unsigned char *keys;
66	SDL_Texture *texture;
67	
68	atexit(&SDL_Quit);
69	SDL_Init(SDL_INIT_VIDEO);
70	
71	input.size.width = 1024;
72	input.size.height = 512;
73	
74	SDL_CreateWindowAndRenderer(input.size.width, input.size.height, SDL_WINDOW_RESIZABLE, &window, &renderer);
75	SDL_SetWindowTitle(window, "Mirai's Miscellaneous Misadventures");
76	
77	SDL_RenderSetLogicalSize(renderer, input.size.width, input.size.height);
78	
79	past = SDL_GetTicks();
80	
81	for (;;)
82	{
83		keys = (void *) SDL_GetKeyboardState(NULL);
84		SDL_GetWindowSize(window, &input.size.width, &input.size.height);
85		input.left = keys[SDL_SCANCODE_LEFT];
86		input.right = keys[SDL_SCANCODE_RIGHT];
87		(*tick)(data, &output, &input);
88		
89		SDL_RenderSetLogicalSize(renderer, output.image.width, output.image.height);
90		texture = mimimi_sdl2_texture(renderer, &output.image);
91		SDL_RenderCopy(renderer, texture, NULL, NULL);
92		SDL_RenderPresent(renderer);
93		
94		current = SDL_GetTicks();
95		delay = current - past;
96		past = current;
97		if (delay < 33) SDL_Delay(33 - delay);
98		
99		while (SDL_PollEvent(&event))
100		{
101			if (event.type == SDL_QUIT) exit(0);
102			if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_q) exit(0);
103		}
104	}
105}