xormod/picture.c

72 lines
1.9 KiB
C
Raw Normal View History

2024-10-05 21:19:26 +00:00
#include <stdio.h>
#include <stdlib.h>
2021-04-12 19:15:41 +00:00
#include "picture.h"
2025-01-07 16:47:17 +00:00
#include "SDL3/SDL_render.h"
2021-04-12 19:15:41 +00:00
2025-01-07 16:47:17 +00:00
Picture *Picture_new(int x, int y, int w, int h, uint32_t color) {
2021-04-12 19:15:41 +00:00
Picture *p = calloc(1, sizeof(Picture));
2025-01-07 16:04:48 +00:00
p->x = x;
p->y = y;
2021-04-12 19:15:41 +00:00
p->w = w;
p->h = h;
p->color = color;
2024-10-05 21:19:26 +00:00
p->s = (w * sizeof(uint32_t) + 7) / 8 * 8;
2025-01-07 16:47:17 +00:00
p->dirty = 1;
2021-04-12 19:15:41 +00:00
2024-10-05 21:19:26 +00:00
p->pixels = malloc(p->s * h);
p->surface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, p->pixels, p->s);
if (p->surface == NULL) {
fprintf(stderr, "Can't create surface: %s\n", SDL_GetError());
exit(-1);
}
2021-04-12 19:15:41 +00:00
return p;
}
2025-01-07 16:47:17 +00:00
void Picture_delete(Picture *p) {
if (p->texture != NULL) SDL_DestroyTexture(p->texture);
SDL_DestroySurface(p->surface);
free(p->pixels);
free(p);
}
2024-11-30 11:59:28 +00:00
typedef uint32_t uint32_8 __attribute__ ((vector_size (8 * sizeof(uint32_t))));
2021-04-12 19:15:41 +00:00
void Picture_render(Picture *p, SDL_Renderer *rend) {
2025-01-07 16:47:17 +00:00
if (!p->dirty) return;
2021-04-12 19:15:41 +00:00
int w = p->w, h = p->h;
2024-11-30 11:59:28 +00:00
uint32_8 c = {
p->color, p->color, p->color, p->color,
p->color, p->color, p->color, p->color
};
const uint32_8 y0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
const uint32_8 x0 = { 0, 1, 2, 3, 4, 5, 6, 7 };
2025-01-07 16:04:48 +00:00
uint32_8 y = y0 + p->y;
2021-04-12 19:15:41 +00:00
for (int j = 0, r = 0; j < h; j++, y += 1) {
2025-01-07 16:04:48 +00:00
uint32_8 x = x0 + p->x;
2024-11-30 11:59:28 +00:00
for (int i = 0; i < w; i += 8, r += 8, x += 8) {
uint32_8 z = (x ^ y) % 9;
uint32_8 f = (z==0) & c;
2021-04-12 19:15:41 +00:00
memcpy(&p->pixels[r], (uint32_t*)&f, sizeof(f));
}
}
if (p->texture) SDL_DestroyTexture(p->texture);
p->texture = SDL_CreateTextureFromSurface(rend, p->surface);
2024-10-05 21:19:26 +00:00
if (p->texture == NULL) {
fprintf(stderr, "Can't create texture: %s\n", SDL_GetError());
exit(-1);
}
2021-04-12 19:15:41 +00:00
SDL_SetTextureBlendMode(p->texture, SDL_BLENDMODE_NONE);
2025-01-07 16:47:17 +00:00
p->dirty = 0;
2021-04-12 19:15:41 +00:00
}
void Picture_move(Picture *p, int x, int y) {
2025-01-07 16:04:48 +00:00
p->x += x;
p->y += y;
2025-01-07 16:47:17 +00:00
p->dirty = 1;
2021-04-12 19:15:41 +00:00
}