summary refs log tree commit diff stats
path: root/skins/badradio/radio-receiver.c
blob: 3e5eea81783bb517b3deba78080e3ad461b881be (plain) (blame)
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
[[clang::import_module("screen")]] [[clang::import_name("set-background-size")]]
extern void set_background_size(int width, int height);

[[clang::import_module("text")]] [[clang::import_name("free")]]
extern void text_free(int handle);
[[clang::import_module("text")]] [[clang::import_name("literal")]]
extern int text_literal(char *text);
[[clang::import_module("screen")]] [[clang::import_name("render-text-object")]]
extern void render_text_object(int handle, int x, int y, int color, bool shadow);

[[clang::import_module("screen")]] [[clang::import_name("get-width")]]
extern int screen_get_width();
[[clang::import_module("screen")]] [[clang::import_name("get-height")]]
extern int screen_get_height();

[[clang::import_module("buttons")]] [[clang::import_name("set-dimensions")]]
extern int button_set_dimensions(int id, int x, int y, int width, int height);

static int text_pixel = -1;
static int text_hbeam = -1;
static int text_vbeam = -1;
static int frame = 0;

static void render_pixel(int x, int y, int color) {
	render_text_object(text_pixel, x, y - 6, color, false);
}

static void render_hbeam(int x, int y, int color) {
	render_text_object(text_hbeam, x, y - 7, color, false);
}

static void render_vbeam(int x, int y, int color) {
	render_text_object(text_vbeam, x, y, color, false);
}

void init() {
	text_pixel = text_literal(".");
	text_hbeam = text_literal("_");
	text_vbeam = text_literal("|");

	// just render them off-screen
	int width = screen_get_width();
	int height = screen_get_height();
	for (int i = 0; button_set_dimensions(i, width, height, 20, 20); i++) {}
}

const char data[] = {
#embed "badapple.dat"
};

const int frames = sizeof(data) / 9662;

const char *cur_frame = data + 62;

static void load_frame() {
	cur_frame = data + frame * 9662 + 62;
}

static int get_color(int x, int y) {
	int tmp = (unsigned char) *(cur_frame + (x >> 3) + (320 / 8) * y);
	tmp <<= (x & 7);
	tmp = (char) tmp;
	tmp >>= 8;
	return tmp;
}

float partframes = 0.0f;

void render(int mouseX, int mouseY, float delta) {
	if (frame >= frames) {
		return;
	}
	load_frame();
	int width = screen_get_width();
	int height = screen_get_height();
	int base_x = (width - 320) / 2;
	int base_y = (height - 240) / 2;
	int skip_list[320] = {0};
	for (int j = 0; j < 240; j++) {
		for (int i = 0; i < 320; i++) {
			if (skip_list[i]) {
				skip_list[i]--;
			}
		}
		int i = 0;
		while (i < 320) {
			if (skip_list[i]) {
				i++;
			} else if (j < 240 - 7 && get_color(i, j) == get_color(i, j + 1) && get_color(i, j) == get_color(i, j + 2) && get_color(i, j) == get_color(i, j + 3) && get_color(i, j) == get_color(i, j + 4) && get_color(i, j) == get_color(i, j + 5) && get_color(i, j) == get_color(i, j + 6)) {
				skip_list[i] = 7;
				render_vbeam(base_x + i, base_y + 240 - j - 7, get_color(i, j));
				i++;
			} else if (i < 320 - 4 && get_color(i, j) == get_color(i + 1, j) && get_color(i, j) == get_color(i + 2, j) && get_color(i, j) == get_color(i + 3, j)) {
				render_hbeam(base_x + i, base_y + 240 - j - 1, get_color(i, j));
				i += 4;
			} else {
				render_pixel(base_x + i, base_y + 240 - j - 1, get_color(i, j));
				i++;
			}
		}
	}
	partframes += delta / 20.0f * 30.0f;
	while (partframes > 1.0f) {
		frame++;
		partframes -= 1.0f;
	}
}