Mirai's Miscellaneous Misadventures

M12 / engines / sdl2.c

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