Mirai's Miscellaneous Misadventures

M15 / engines / sdl2.c

1// copyright 2022 zamfofex
2// license: AGPLv3 or later
3
4#include <stdlib.h>
5#include <SDL2/SDL.h>
6
7#include "../mimimi.h"
8
9struct mirai_sdl2
10{
11	SDL_Renderer *renderer;
12	struct mirai_image *images;
13	SDL_Texture **textures;
14};
15
16static void mirai_sdl2_stamp(void *opaque, int x, int y, struct mirai_image *image)
17{
18	struct mirai_sdl2 *data = opaque;
19	SDL_Renderer *renderer = data->renderer;
20	
21	SDL_Rect rect;
22	rect.x = x;
23	rect.y = y;
24	rect.w = image->width;
25	rect.h = image->height;
26	
27	int i = image - data->images;
28	
29	SDL_RenderCopy(renderer, data->textures[i], NULL, &rect);
30}
31
32int main(int argc, char **argv)
33{
34	atexit(&SDL_Quit);
35	
36	SDL_Init(SDL_INIT_VIDEO);
37	
38	SDL_Window *window;
39	SDL_Renderer *renderer;
40	
41	SDL_CreateWindowAndRenderer(mirai_width, mirai_height, 0, &window, &renderer);
42	SDL_RenderSetLogicalSize(renderer, mirai_width, mirai_height);
43	SDL_SetWindowTitle(window, "Mirai's Miscellaneous Misadventures");
44	
45	struct mirai_image *images = mirai_assets();
46	struct mirai_image *image = images;
47	int image_count = 0;
48	
49	while (image->width != 0)
50	{
51		image_count++;
52		image++;
53	}
54	image = images;
55	
56	SDL_Texture **textures = malloc(image_count * sizeof *textures);
57	
58	for (int i = 0 ; image->width != 0 ; i++)
59	{
60		SDL_Surface *surface = SDL_CreateRGBSurface(0, image->width, image->height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
61		for (int x = 0 ; x < image->width ; x++)
62		for (int y = 0 ; y < image->height ; y++)
63		{
64			static unsigned char xterm[] = {0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF};
65			
66			Uint32 o = x * 4 + y * surface->pitch;
67			Uint32 *pixel = (Uint32 *) ((char *) surface->pixels + o);
68			
69			Uint32 r, g, b, a;
70			unsigned char color = image->colors[x + y * image->width];
71			if (color == 0)
72			{
73				r = 0x00;
74				g = 0x00;
75				b = 0x00;
76				a = 0x00;
77			}
78			else
79			{
80				color -= 16;
81				r = xterm[(color / 36) % 6];
82				g = xterm[(color / 6) % 6];
83				b = xterm[color % 6];
84				a = 0xFF;
85			}
86			
87			*pixel = (r << 24) | (g << 16) | (b << 8) | (a << 0);
88		}
89		
90		textures[i] = SDL_CreateTextureFromSurface(renderer, surface);
91		
92		SDL_FreeSurface(surface);
93		image++;
94	}
95	
96	struct mirai_sdl2 data = {renderer, images, textures};
97	
98	struct mirai_engine engine = {&data, &mirai_sdl2_stamp};
99	struct mirai_game *game = malloc(mirai_game_size);
100	mirai_start(game, &engine);
101	
102	Uint32 past = SDL_GetTicks();
103	
104	for (;;)
105	{
106		Uint32 current = SDL_GetTicks();
107		Uint32 delay = current - past;
108		past = current;
109		if (delay < 33) SDL_Delay(33 - delay);
110		
111		SDL_Event event;
112		while (SDL_PollEvent(&event))
113		{
114			if (event.type == SDL_QUIT) return 0;
115			
116			if (event.type == SDL_KEYDOWN)
117			{
118				switch (event.key.keysym.sym)
119				{
120					default: continue;
121					case SDLK_q: return 0;
122				}
123			}
124		}
125		
126		struct mirai_keys keys = {0, 0};
127		
128		unsigned char *keyboard = SDL_GetKeyboardState(NULL);
129		if (keyboard[SDL_SCANCODE_LEFT]) keys.left = 1;
130		if (keyboard[SDL_SCANCODE_RIGHT]) keys.right = 1;
131		
132		SDL_Rect rect = {0, 0, mirai_width, mirai_height};
133		SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
134		SDL_RenderClear(renderer);
135		SDL_SetRenderDrawColor(renderer, 0xEE, 0xEE, 0xEE, 0xFF);
136		SDL_RenderFillRect(renderer, &rect);
137		mirai_step(game, keys);
138		SDL_RenderPresent(renderer);
139	}
140}