-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathilda-display.c
More file actions
116 lines (108 loc) · 3.43 KB
/
ilda-display.c
File metadata and controls
116 lines (108 loc) · 3.43 KB
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
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <SDL2/SDL.h>
#include "ilda-decoder.h"
#define STRICT_MODE 0x8000
static ssize_t read_file(void *opaque, void *buffer, size_t len) {
ssize_t r = read((int)(long)opaque & ~STRICT_MODE, buffer, len);
if (r == 0) {
if ((int)(long)opaque & STRICT_MODE) {
fprintf(stderr, "end of file encountered before ILDA end marker\n");
exit(1);
}
lseek((int)(long)opaque, 0, SEEK_SET);
r = read((int)(long)opaque, buffer, len);
}
return r;
}
#define DIM 600
int transform(int x) { return (x + 32768) * 599 / 65535; }
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: ilda-display FILE\n");
fprintf(stderr, " Press space bar to pause and Q to quit\n");
fprintf(
stderr,
" Use strict mode if ILDA_STRICT_MODE environment variable exists\n");
exit(1);
}
int f = open(argv[1], 0);
if (f < 0) {
perror("cannot open file");
exit(1);
}
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "cannot initialize SDL\n");
exit(1);
}
SDL_Window *window =
SDL_CreateWindow("ILDA display", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, DIM, DIM, SDL_WINDOW_SHOWN);
if (!window) {
fprintf(stderr, "cannot create SDL window\n");
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
int pause = 0;
ilda_state_t ilda;
int strict_mode = getenv("ILDA_STRICT_MODE") == NULL ? 0 : STRICT_MODE;
ilda_init(&ilda, read_file, (void *)((long)f | strict_mode), strict_mode);
ilda_pos_t last_point = {0, 0, 0};
for (;;) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT ||
(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_q))
goto bye;
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_SPACE)
pause ^= 1;
}
if (pause) {
SDL_Delay(40);
continue;
}
const ilda_header_t *header = ilda_read_next_header(&ilda);
if (header == NULL) {
fprintf(stderr, "error when reading ILDA file: %s\n", ilda.error);
exit(1);
}
if (ilda_is_end_of_file(header)) {
lseek(f, 0, SEEK_SET);
continue;
}
if (ilda_is_palette(header)) {
if (ilda_read_palette(&ilda)) {
fprintf(stderr, "error when reading palette: %s\n", ilda.error);
exit(1);
}
} else {
static ilda_point_t buffer[65536];
if (ilda_read_records(&ilda, buffer, sizeof buffer)) {
fprintf(stderr, "error when reading records: %s\n", ilda.error);
exit(1);
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
for (size_t i = 0; i < header->number_of_records; i++) {
const ilda_point_t *point = &buffer[i];
if (!ilda_is_blanking(point->status_code)) {
SDL_SetRenderDrawColor(renderer, point->color.r, point->color.g,
point->color.b, SDL_ALPHA_OPAQUE);
SDL_RenderDrawLine(
renderer, transform(last_point.x), DIM - transform(last_point.y),
transform(point->pos.x), DIM - transform(point->pos.y));
}
memcpy(&last_point, point, sizeof last_point);
}
SDL_RenderPresent(renderer);
SDL_Delay(40);
}
}
bye:
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}