-
Notifications
You must be signed in to change notification settings - Fork 9
/
animation.c
100 lines (80 loc) · 2.28 KB
/
animation.c
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
/*
* A framebuffer animation daemon
*
* Copyright (C) 2012 Alexander Lukichev
*
* Alexander Lukichev <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <stdlib.h>
#include <time.h>
#include "animation.h"
#include "bmp.h"
#include "fb.h"
#include "log.h"
#include "string_list.h"
static inline void center2top_left(struct image_info *image, int cx, int cy,
int *top_left_x, int *top_left_y)
{
*top_left_x = cx - image->width / 2;
*top_left_y = cy - image->height / 2;
}
/**
* Run the animation either infinitely or until 'frames' frames have been shown
*/
int animation_run(struct animation *banner, int frames)
{
const int infinitely = frames < 0;
int fnum = banner->frame_num;
int rc = 0;
while (infinitely || frames--) {
int x, y;
struct image_info *frame = &banner->frames[fnum];
center2top_left(frame, banner->x, banner->y, &x, &y);
rc = fb_write_bitmap(banner->fb, x, y, frame);
if (rc)
break;
if (++fnum == banner->frame_count)
fnum = 0;
if (banner->interval) {
const struct timespec sleep_time = {
.tv_sec = banner->interval / 1000,
.tv_nsec = (banner->interval % 1000) * 1000000,
};
nanosleep(&sleep_time, NULL);
}
}
banner->frame_num = fnum;
return rc;
}
int animation_init(struct string_list *filenames, int filenames_count,
struct screen_info *fb, struct animation *a)
{
int i;
int screen_w, screen_h;
if (!fb->fb_size) {
LOG(LOG_ERR, "Unable to init animation against uninitialized "
"framebuffer");
return -1;
}
a->fb = fb;
a->frame_num = 0;
a->frame_count = filenames_count;
a->frames = malloc(filenames_count * sizeof(struct image_info));
if (a->frames == NULL) {
LOG(LOG_ERR, "Unable to get %zu bytes of memory for animation",
filenames_count * sizeof(struct image_info));
return -1;
}
for (i = 0; i < filenames_count; ++i, filenames = filenames->next)
if (bmp_read(filenames->s, &a->frames[i]))
return -1;
screen_w = fb->width;
screen_h = fb->height;
a->x = screen_w / 2;
a->y = screen_h / 2;
return 0;
}