diff libmlk-core/mlk/core/texture.c @ 431:8f59201dc76b

core: cleanup hierarchy
author David Demelier <markand@malikania.fr>
date Sat, 15 Oct 2022 20:23:14 +0200
parents src/libmlk-core/core/texture.c@1645433e008d
children e1eebc6bf25d
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-core/mlk/core/texture.c	Sat Oct 15 20:23:14 2022 +0200
@@ -0,0 +1,178 @@
+/*
+ * texture.c -- basic texture management
+ *
+ * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "color.h"
+#include "error.h"
+#include "texture.h"
+#include "texture_p.h"
+#include "util.h"
+#include "window.h"
+#include "window_p.h"
+
+int
+texture_new(struct texture *tex, unsigned int w, unsigned int h)
+{
+	assert(tex);
+	assert(w);
+	assert(h);
+
+	tex->handle = SDL_CreateTexture(RENDERER(),
+	    SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
+
+	if (!tex->handle) {
+		tex->w = tex->h = 0;
+		return ERR_SDL;
+	}
+
+	tex->w = w;
+	tex->h = h;
+
+	return 0;
+}
+
+int
+texture_ok(const struct texture *tex)
+{
+	return tex && tex->handle && tex->w && tex->h;
+}
+
+int
+texture_set_blend_mode(struct texture *tex, enum texture_blend blend)
+{
+	assert(tex);
+	assert(blend >= TEXTURE_BLEND_NONE && blend <= TEXTURE_BLEND_MODULATE);
+
+	static const SDL_BlendMode table[] = {
+		[TEXTURE_BLEND_NONE] = SDL_BLENDMODE_NONE,
+		[TEXTURE_BLEND_BLEND] = SDL_BLENDMODE_BLEND,
+		[TEXTURE_BLEND_ADD] = SDL_BLENDMODE_ADD,
+		[TEXTURE_BLEND_MODULATE] = SDL_BLENDMODE_MOD
+	};
+
+	if (SDL_SetTextureBlendMode(tex->handle, table[blend]) < 0)
+		return errorf("%s", SDL_GetError());
+
+	return 0;
+}
+
+int
+texture_set_alpha_mod(struct texture *tex, unsigned int alpha)
+{
+	assert(texture_ok(tex));
+	assert(alpha <= 255);
+
+	if (SDL_SetTextureAlphaMod(tex->handle, alpha) < 0)
+		return errorf("%s", SDL_GetError());
+
+	return 0;
+}
+
+int
+texture_set_color_mod(struct texture *tex, unsigned long color)
+{
+	assert(texture_ok(tex));
+
+	if (SDL_SetTextureColorMod(tex->handle, COLOR_R(color), COLOR_G(color), COLOR_B(color)) < 0)
+		return errorf("%s", SDL_GetError());
+
+	return 0;
+}
+
+int
+texture_draw(const struct texture *tex, int x, int y)
+{
+	assert(tex);
+
+	SDL_Rect dst = {
+		.x = x,
+		.y = y,
+		.w = tex->w,
+		.h = tex->h
+	};
+
+	if (SDL_RenderCopy(RENDERER(), tex->handle, NULL, &dst) < 0)
+		return errorf("%s", SDL_GetError());
+
+	return 0;
+}
+
+int
+texture_scale(const struct texture *tex,
+              int src_x,
+              int src_y,
+              unsigned src_w,
+              unsigned src_h,
+              int dst_x,
+              int dst_y,
+              unsigned dst_w,
+              unsigned dst_h,
+              double angle)
+{
+	const SDL_Rect src = {
+		.x = src_x,
+		.y = src_y,
+		.w = src_w,
+		.h = src_h
+	};
+	const SDL_Rect dst = {
+		.x = dst_x,
+		.y = dst_y,
+		.w = dst_w,
+		.h = dst_h
+	};
+
+	if (SDL_RenderCopyEx(RENDERER(), tex->handle, &src, &dst, angle, NULL, SDL_FLIP_NONE) < 0)
+		return errorf("%s", SDL_GetError());
+
+	return 0;
+}
+
+void
+texture_finish(struct texture *tex)
+{
+	assert(tex);
+
+	if (tex->handle)
+		SDL_DestroyTexture(tex->handle);
+
+	memset(tex, 0, sizeof (*tex));
+}
+
+/* private */
+
+int
+texture_from_surface(struct texture *tex, SDL_Surface *surface)
+{
+	assert(tex);
+	assert(surface);
+
+	if (!(tex->handle = SDL_CreateTextureFromSurface(RENDERER(), surface))) {
+		tex->w = tex->h = 0;
+		return ERR_SDL;
+	}
+
+	tex->w = surface->w;
+	tex->h = surface->h;
+
+	SDL_FreeSurface(surface);
+
+	return 0;
+}