Mirai's Miscellaneous Misadventures
M46 / engines / sdl2.c
1
2
3
4#include <stdlib.h>
5#include <SDL2/SDL.h>
6#include <mimimi.h>
7
8static void *mimimi_sdl2_texture(void *data, 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, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
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 = (a << 24) | (a << 16) | (a << 8) | 0xFF;
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 = (r << 24) | (g << 16) | (b << 8) | (a << 0);
47 }
48 }
49
50 texture = SDL_CreateTextureFromSurface(data, surface);
51
52 SDL_FreeSurface(surface);
53
54 return texture;
55}
56
57static void mimimi_sdl2_invalidate(void *data, void *texture)
58{
59 (void) data;
60 SDL_DestroyTexture(texture);
61}
62
63static void mimimi_sdl2_stamp(void *data, int x, int y, void *texture)
64{
65 SDL_Rect rect;
66
67 rect.x = x;
68 rect.y = y;
69 SDL_QueryTexture(texture, NULL, NULL, &rect.w, &rect.h);
70
71 SDL_RenderCopy(data, texture, NULL, &rect);
72}
73
74int mimimi_sdl2(void (*start)(void *chapter, struct mimimi_engine *engine), void (*tick)(void *chapter, unsigned char left, unsigned char right), unsigned long int chapter_size)
75{
76 static SDL_Rect rect = {0, 0, 512, 256};
77
78 SDL_Window *window;
79 SDL_Renderer *renderer;
80 struct mimimi_engine engine;
81 void *chapter;
82 Uint32 past, current, delay;
83 SDL_Event event;
84 unsigned char *keys;
85
86 atexit(&SDL_Quit);
87
88 SDL_Init(SDL_INIT_VIDEO);
89
90 SDL_CreateWindowAndRenderer(rect.w, rect.h, SDL_WINDOW_RESIZABLE, &window, &renderer);
91 SDL_RenderSetLogicalSize(renderer, rect.w, rect.h);
92 SDL_SetWindowTitle(window, "mimimi game");
93
94 engine.data = renderer;
95 engine.texture = &mimimi_sdl2_texture;
96 engine.invalidate = &mimimi_sdl2_invalidate;
97 engine.stamp = &mimimi_sdl2_stamp;
98 engine.size.width = 512;
99 engine.size.height = 256;
100
101 chapter = malloc(chapter_size);
102 if (chapter == NULL) return 1;
103
104 (*start)(chapter, &engine);
105
106 past = SDL_GetTicks();
107
108 for (;;)
109 {
110 current = SDL_GetTicks();
111 delay = current - past;
112 past = current;
113 if (delay < 33) SDL_Delay(33 - delay);
114
115 while (SDL_PollEvent(&event))
116 {
117 if (event.type == SDL_QUIT) return 0;
118
119 if (event.type == SDL_KEYDOWN)
120 {
121 switch (event.key.keysym.sym)
122 {
123 default: continue;
124 case SDLK_q: return 0;
125 }
126 }
127 }
128
129 keys = (void *) SDL_GetKeyboardState(NULL);
130
131 SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
132 SDL_RenderClear(renderer);
133 SDL_SetRenderDrawColor(renderer, 0xEE, 0xEE, 0xEE, 0xFF);
134 SDL_RenderFillRect(renderer, &rect);
135 (*tick)(chapter, keys[SDL_SCANCODE_LEFT], keys[SDL_SCANCODE_RIGHT]);
136 SDL_RenderPresent(renderer);
137 }
138}