summaryrefslogtreecommitdiff
path: root/src/rendering.c
blob: e62e746b4ddada46872a772a7da7702424b823dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <stdio.h>
#include <string.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>

#define ENGINE_INTERNALS
#include <engine/engine.h>
#include <engine/rendering.h>

/* Extern globals */
extern Platform *GLOBAL_PLATFORM;

/* Globals */
#define drawcall_limit (64 * 1024)
RenderDrawCall drawcalls[drawcall_limit];
i32 drawcall_len = 0;

/* Implementations */

/* Clear the screen,
 * To be used inbetween draw calls */
void render_begin(Window *w) {
#ifdef _DEBUG
	SDL_SetRenderDrawColor(w->renderer, 0x10, 0x0a, 0x33, 0x00);
#else
	SDL_SetRenderDrawColor(w->renderer, 0x00, 0x00, 0x00, 0x00);
#endif
	SDL_RenderClear(w->renderer);
}

void render_present(Window *w) {
	for (i32 i = 0; i < drawcall_len; i++) {
		RenderDrawCall dc = drawcalls[i];
		switch (dc.type) {
			case RenderDrawCallType_UITree:
				render_uitree(w, dc.data.data);
				break;
			case RenderDrawCallType_Text:
				LOG("RenderDrawCallType_Text rendering not implemented!");
				break;
			case RenderDrawCallType_Sprite:
				{
#ifdef _DEBUG
					if (dc.data.sprite.sprite == NULL) {
						__asm__("int3;");
						WARN("Sprite %lx in drawcall %d/%d had NULL reference", dc.data.sprite.sprite, i, drawcall_len);

						drawcall_len = 0;
						SDL_RenderPresent(w->renderer);
						exit(EXIT_FAILURE);
					}
#endif
					Sprite s = *dc.data.sprite.sprite;
					Texture *t = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[s.texture_id];
					i32 ts = t->tilesize;
					SDL_Rect src = {
						s.coord.x,
						s.coord.y,
						ts,ts
					};
					SDL_Rect dst = {
						dc.data.sprite.x,
						dc.data.sprite.y,
						ts * dc.data.sprite.scale,
						ts * dc.data.sprite.scale,
					};
					SDL_SetTextureColorMod(t->texture,
							dc.data.sprite.mod.r,
							dc.data.sprite.mod.g,
							dc.data.sprite.mod.b);
					SDL_RenderCopy(
						w->renderer,
						t->texture,
						&src, &dst);
				}
				break;
			default:
				break;
		}
	}

	drawcall_len = 0;

	SDL_RenderPresent(w->renderer);
}

void drawcall_reset(void) {
	drawcall_len = 0;
}

void engine_window_resize_pointers(i32* w, i32* h) {
	GLOBAL_PLATFORM->window->game_w = w;
	GLOBAL_PLATFORM->window->game_h = h;
}

void engine_window_resize_pointers_reset(void) {
	GLOBAL_PLATFORM->window->game_w = NULL;
	GLOBAL_PLATFORM->window->game_h = NULL;
}

void engine_draw_uitree(UITree *t) {
	if (drawcall_len + 1 >= drawcall_limit) return;
	drawcalls[drawcall_len++] = (RenderDrawCall){
		.type = RenderDrawCallType_UITree,
		.data.data = (void*)t
	};
}

void engine_draw_sprite(Sprite *s, v2_i32 *pos, f32 scale) {
	if (drawcall_len + 1 >= drawcall_limit) return;
#ifdef _DEBUG
	if (s == NULL) __asm__("int3;");
#endif
	drawcalls[drawcall_len++] = (RenderDrawCall){
		.type = RenderDrawCallType_Sprite,
		.data.sprite = {
			.sprite = s,
			.x = pos->x,
			.y = pos->y,
			.scale = scale,
			.mod = {0xFF, 0xFF, 0xFF, 0xFF},
		}
	};
}

void engine_draw_sprite_ex(Sprite *s, v2_i32 *pos, f32 scale, Engine_color colormod) {
	if (drawcall_len + 1 >= drawcall_limit) return;
#ifdef _DEBUG
	if (s == NULL) __asm__("int3;");
#endif
	drawcalls[drawcall_len++] = (RenderDrawCall){
		.type = RenderDrawCallType_Sprite,
		.data.sprite = {
			.sprite = s,
			.x = pos->x,
			.y = pos->y,
			.scale = scale,
			.mod = {colormod.r, colormod.g, colormod.b, colormod.a},
		}
	};
}


Sprite sprite_new(u64 tid, u8 coord) {
	const i32 ts = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[tid]->tilesize;
	return (Sprite){.texture_id = tid, (v2_i32){
		.x = ts *  (coord & 0x0F),
		.y = ts * ((coord & 0xF0) >> 4),
	}};
}