Mirai's Miscellaneous Misadventures
M47 / engines / sdl2.c
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <mimimi.h>
static void *mimimi_sdl2_texture(void *data, struct mimimi_image *image)
{
static unsigned char rch[] = {0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF};
static unsigned char gch[] = {0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF};
static unsigned char bch[] = {0x22, 0x55, 0x88, 0xBB, 0xEE};
int x, y;
unsigned char color;
SDL_Texture *texture;
SDL_Surface *surface;
Uint32 offset;
Uint32 *pixel;
Uint32 r, g, b, a;
surface = SDL_CreateRGBSurface(0, image->width, image->height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
for (x = 0 ; x < image->width ; x++)
for (y = 0 ; y < image->height ; y++)
{
offset = x * 4 + y * surface->pitch;
pixel = (Uint32 *) ((char *) surface->pixels + offset);
color = image->colors[x + y * image->width];
if (color == 0)
{
*pixel = 0;
}
else if (color < 0x10)
{
a = color * 0x11;
*pixel = (a << 24) | (a << 16) | (a << 8) | 0xFF;
}
else
{
color -= 0x10;
r = rch[(color / 40) % 6];
g = gch[(color / 5) % 8];
b = bch[(color / 1) % 5];
a = 0xFF;
*pixel = (r << 24) | (g << 16) | (b << 8) | (a << 0);
}
}
texture = SDL_CreateTextureFromSurface(data, surface);
SDL_FreeSurface(surface);
return texture;
}
static void mimimi_sdl2_invalidate(void *data, void *texture)
{
(void) data;
SDL_DestroyTexture(texture);
}
static void mimimi_sdl2_stamp(void *data, int x, int y, void *texture)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
SDL_QueryTexture(texture, NULL, NULL, &rect.w, &rect.h);
SDL_RenderCopy(data, texture, NULL, &rect);
}
int 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)
{
static SDL_Rect rect = {0, 0, 512, 256};
SDL_Window *window;
SDL_Renderer *renderer;
struct mimimi_engine engine;
void *chapter;
Uint32 past, current, delay;
SDL_Event event;
unsigned char *keys;
atexit(&SDL_Quit);
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(rect.w, rect.h, SDL_WINDOW_RESIZABLE, &window, &renderer);
SDL_RenderSetLogicalSize(renderer, rect.w, rect.h);
SDL_SetWindowTitle(window, "mimimi game");
engine.data = renderer;
engine.texture = &mimimi_sdl2_texture;
engine.invalidate = &mimimi_sdl2_invalidate;
engine.stamp = &mimimi_sdl2_stamp;
engine.size.width = 512;
engine.size.height = 256;
chapter = malloc(chapter_size);
if (chapter == NULL) return 1;
(*start)(chapter, &engine);
past = SDL_GetTicks();
for (;;)
{
current = SDL_GetTicks();
delay = current - past;
past = current;
if (delay < 33) SDL_Delay(33 - delay);
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) return 0;
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
default: continue;
case SDLK_q: return 0;
}
}
}
keys = (void *) SDL_GetKeyboardState(NULL);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0xEE, 0xEE, 0xEE, 0xFF);
SDL_RenderFillRect(renderer, &rect);
(*tick)(chapter, keys[SDL_SCANCODE_LEFT], keys[SDL_SCANCODE_RIGHT]);
SDL_RenderPresent(renderer);
}
}