Mirai's Miscellaneous Misadventures
M4 / 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 - image->width / 2;
20 rect.y = y - image->height;
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 printf("%d %d\n", image->width, image->height);
59 for (int x = 0 ; x < image->width ; x++)
60 for (int y = 0 ; y < image->height ; y++)
61 {
62 static unsigned char xterm[] = {0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF};
63
64 Uint32 o = x * 4 + y * surface->pitch;
65 Uint32 *pixel = (Uint32 *) ((char *) surface->pixels + o);
66
67 Uint32 r, g, b, a;
68 unsigned char color = image->colors[x + y * image->width];
69 if (color == 0)
70 {
71 r = 0x00;
72 g = 0x00;
73 b = 0x00;
74 a = 0x00;
75 }
76 else
77 {
78 color -= 16;
79 r = xterm[(color / 36) % 6];
80 g = xterm[(color / 6) % 6];
81 b = xterm[color % 6];
82 a = 0xFF;
83 }
84
85 *pixel = (r << 24) | (g << 16) | (b << 8) | (a << 0);
86 }
87
88 textures[i] = SDL_CreateTextureFromSurface(renderer, surface);
89
90 SDL_FreeSurface(surface);
91 image++;
92 }
93
94 struct mirai_sdl2 data = {renderer, images, textures};
95
96 struct mirai_engine engine = {&data, &mirai_sdl2_stamp};
97 struct mirai_game *game = malloc(mirai_game_size);
98 mirai_start(game, &engine);
99
100 Uint32 past = SDL_GetTicks();
101
102 for (;;)
103 {
104 Uint32 current = SDL_GetTicks();
105 Uint32 delay = current - past;
106 if (delay < 33) SDL_Delay(33 - delay);
107 past = current;
108
109 SDL_Event event;
110 while (SDL_PollEvent(&event))
111 {
112 if (event.type == SDL_QUIT) return 0;
113
114 if (event.type == SDL_KEYDOWN)
115 {
116 switch (event.key.keysym.sym)
117 {
118 default: continue;
119 case SDLK_q: return 0;
120 }
121 }
122 }
123
124 struct mirai_keys keys = {0, 0};
125
126 unsigned char *keyboard = SDL_GetKeyboardState(NULL);
127 if (keyboard[SDL_SCANCODE_LEFT]) keys.left = 1;
128 if (keyboard[SDL_SCANCODE_RIGHT]) keys.right = 1;
129
130 SDL_SetRenderDrawColor(renderer, 0xEE, 0xEE, 0xEE, 0xEE);
131 SDL_RenderClear(renderer);
132 SDL_SetRenderDrawColor(renderer, 0x33, 0x33, 0x33, 0x33);
133 mirai_step(game, keys);
134 SDL_RenderPresent(renderer);
135 }
136}