summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--skins/badradio/.gitignore2
-rw-r--r--skins/badradio/badradio/pack.mcmeta6
-rwxr-xr-xskins/badradio/build_script.sh20
-rw-r--r--skins/badradio/radio-receiver.c107
4 files changed, 135 insertions, 0 deletions
diff --git a/skins/badradio/.gitignore b/skins/badradio/.gitignore
new file mode 100644
index 0000000..08aea49
--- /dev/null
+++ b/skins/badradio/.gitignore
@@ -0,0 +1,2 @@
+*.zip
+*.dat
diff --git a/skins/badradio/badradio/pack.mcmeta b/skins/badradio/badradio/pack.mcmeta
new file mode 100644
index 0000000..38e08e5
--- /dev/null
+++ b/skins/badradio/badradio/pack.mcmeta
@@ -0,0 +1,6 @@
+{
+  "pack": {
+    "description": "BadRadio!!",
+    "pack_format": 34
+  }
+}
diff --git a/skins/badradio/build_script.sh b/skins/badradio/build_script.sh
new file mode 100755
index 0000000..9a01edc
--- /dev/null
+++ b/skins/badradio/build_script.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -e
+
+s_EXPORTED_FUNCTIONS="-s EXPORTED_FUNCTIONS=_init,_render"
+
+shared_flags="-Oz -flto -fno-inline -fno-unroll-loops -mnontrapping-fptoint"
+compile_flags="$shared_flags --std=c23"
+link_flags="$shared_flags -s MALLOC=emmalloc -s ASSERTIONS=0 -s INITIAL_MEMORY=$((70*16*65536)) -s TOTAL_STACK=16384 -s STANDALONE_WASM=1 -s PURE_WASI=1 -s STACK_OVERFLOW_CHECK=0 -s WASM_BIGINT=1 -s ABORTING_MALLOC=0 -s MEMORY_GROWTH_GEOMETRIC_STEP=0 -s ALLOW_MEMORY_GROWTH=1"
+
+emcc --no-entry $s_EXPORTED_FUNCTIONS $link_flags $compile_flags -o radio-receiver.wasm radio-receiver.c
+
+mkdir -p badradio/assets/pirate-radio/guis
+cp radio-receiver.wasm badradio/assets/pirate-radio/guis/radio-receiver.wasm
+
+cd badradio
+rm badradio.zip || true
+zip -r badradio *
+
+exit 0
diff --git a/skins/badradio/radio-receiver.c b/skins/badradio/radio-receiver.c
new file mode 100644
index 0000000..3e5eea8
--- /dev/null
+++ b/skins/badradio/radio-receiver.c
@@ -0,0 +1,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;
+	}
+}