summaryrefslogtreecommitdiff
path: root/user/apple.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-30 10:50:50 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-30 11:25:42 -0400
commitbe98bd487f9a38b2bdb5d48b17a76010809429d3 (patch)
treec9b9271035f1d75d06d0a1776daf5500d6b0ef6d /user/apple.c
parentinflate / deflate (diff)
downloadcomus-be98bd487f9a38b2bdb5d48b17a76010809429d3.tar.gz
comus-be98bd487f9a38b2bdb5d48b17a76010809429d3.tar.bz2
comus-be98bd487f9a38b2bdb5d48b17a76010809429d3.zip
lossy RLE for apple
Diffstat (limited to 'user/apple.c')
-rw-r--r--user/apple.c119
1 files changed, 77 insertions, 42 deletions
diff --git a/user/apple.c b/user/apple.c
index a0a7e9a..578a075 100644
--- a/user/apple.c
+++ b/user/apple.c
@@ -1,62 +1,81 @@
-
#include <incbin.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
INCBIN(APPLE, "data/apple.bin");
-#define APPLE_WIDTH 256
-#define APPLE_HEIGHT 144
-#define APPLE_FPS 12
-#define APPLE_FRAMES 2630
+#define APPLE_WIDTH 480
+#define APPLE_HEIGHT 360
+#define APPLE_FPS 30
+#define APPLE_FRAMES 6572
+#define VSYNC_FPS 60
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
// returned from drm
static uint32_t *fb;
static int width, height, bpp, scale;
+size_t fb_size;
-// meta
-static size_t frame = 0;
-static size_t frame_size;
-static size_t ticks_off;
+// decompress state
+static size_t d_offset = 0, d_length = 0;
+static unsigned char d_value;
-#define PIXEL(x, y) \
- gAPPLEData[offset + \
- (((x + APPLE_WIDTH % APPLE_WIDTH) / scale) + \
- ((y + APPLE_HEIGHT % APPLE_HEIGHT) / scale) * APPLE_WIDTH)]
+// frame counter
+static size_t last_frame = SIZE_MAX, frame = 0;
-static void draw_frame(void)
-{
- size_t offset = frame_size * frame;
+// frame buffer
+static unsigned char frame_buf[APPLE_WIDTH * APPLE_HEIGHT];
- for (int y = 0; y < APPLE_HEIGHT * scale; y++) {
- for (int x = 0; x < APPLE_WIDTH * scale; x++) {
- uint8_t colors[9];
- colors[0] = PIXEL(x, y);
- colors[1] = PIXEL(x - 1, y);
- colors[2] = PIXEL(x + 1, y);
- colors[3] = PIXEL(x, y - 1);
- colors[4] = PIXEL(x - 1, y - 1);
- colors[5] = PIXEL(x + 1, y - 1);
- colors[6] = PIXEL(x, y + 1);
- colors[7] = PIXEL(x - 1, y + 1);
- colors[8] = PIXEL(x + 1, y + 1);
+// backbuffer
+static uint32_t *back_fb;
- // anti aliasing
- uint8_t color = (colors[0] + colors[0] + colors[0] + colors[0] +
- colors[1] + colors[2] + colors[3] + colors[4] +
- colors[5] + colors[6] + colors[7] + colors[8]) /
- 12;
+// start tick
+static size_t tick_start;
- fb[x + y * width] = (color << 16) | (color << 8) | (color << 0);
- }
+static unsigned char read_byte(void)
+{
+ while (d_length < 1) {
+ unsigned char len;
+
+ d_length = 0;
+ do {
+ len = gAPPLEData[d_offset++];
+ d_length += len;
+ } while (len == 255);
+ d_value = gAPPLEData[d_offset++];
}
- frame = ((ticks() - ticks_off) / (1000 / APPLE_FPS));
+ d_length--;
+ return d_value;
+}
- if (frame >= APPLE_FRAMES)
- exit(0);
+static void read_frame(void)
+{
+ for (size_t i = 0; i < sizeof(frame_buf); i++)
+ frame_buf[i] = read_byte();
+}
+
+static void swap_buffers(void)
+{
+ // terrible :3
+ uint32_t count = width * height / 2;
+ __asm__ volatile("rep movsq" ::"S"(back_fb), "D"(fb), "c"(count)
+ : "memory");
+}
+
+static void draw_frame(void)
+{
+ for (int y = 0; y < APPLE_HEIGHT * scale; y++) {
+ for (int x = 0; x < APPLE_WIDTH * scale; x++) {
+ unsigned char color =
+ frame_buf[(x / scale) + (y / scale) * APPLE_WIDTH];
+ back_fb[x + y * width] = (color << 16) | (color << 8) |
+ (color << 0);
+ }
+ }
}
int main(void)
@@ -68,12 +87,28 @@ int main(void)
return 1;
}
- ticks_off = ticks();
- frame_size = APPLE_WIDTH * APPLE_HEIGHT;
+ fb_size = (width * height * bpp) / 8;
+ back_fb = malloc(fb_size);
+ if (back_fb == NULL) {
+ fprintf(stderr, "failure but 2\n");
+ return 1;
+ }
+
+ tick_start = ticks();
scale = MIN(width / APPLE_WIDTH, height / APPLE_HEIGHT);
- while (1)
- draw_frame();
+ while (1) {
+ if (last_frame != frame) {
+ read_frame();
+ draw_frame();
+ swap_buffers();
+ }
+
+ last_frame = frame;
+ frame = ((ticks() - tick_start) / (1000 / APPLE_FPS));
+ if (frame >= APPLE_FRAMES)
+ break;
+ }
return 0;
}