summaryrefslogtreecommitdiff
path: root/src/display.h
blob: b42c69ec868e950ba4adb647eb488005a3d87f9b (plain)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * Copyright (C) 2016 by Daniel Friesel
 *
 * License: You may use, redistribute and/or modify this file under the terms
 * of either:
 * * The GNU LGPL v3 (see COPYING and COPYING.LESSER), or
 * * The 3-clause BSD License (see COPYING.BSD)
 *
 */

#include <avr/io.h>
#include <stdlib.h>

/**
 * Describes the type of an animation object. The Storage class reserves four
 * bits for the animation type, so up to 16 types are supported.
 */
enum class AnimationType : uint8_t {
	TEXT = 1,
	FRAMES = 2
};

/**
 * Generic struct for anything which can be displayed, e.g. texts or
 * sequences of frames.
 */
struct animation {
	/**
	 * Specific kind of animation described in this struct. Controls the
	 * behaviour of Display::multiplex() and Display::update().
	 */
	AnimationType type;

	/**
	 * Length of data in bytes
	 */
	uint16_t length;

	/**
	 * * If type == AnimationType::TEXT: Text scroll speed in columns per TODO
	 * * If type == AnimationType::FRAMES: Frames per TODO
	 */
	uint8_t speed;

	/**
	 * Delay after the last text symbol / animation frame. Not yet supported.
	 */
	uint8_t delay;

	/**
	 * Scroll mode / direction. Not yet supported.
	 */
	uint8_t direction;

	/**
	 * * If type == AnimationType::TEXT: character array pointing to the
	 *   animation text in standard ASCII format (+ special font chars)
	 * * If type == AnimationType::FRAMES: Frame array. Each element encodes
	 *   a display column (starting with the leftmost one), each group of
	 *   eight elements is a frame.
	 */
	uint8_t *data;
};

typedef struct animation animation_t;

/**
 * Controls the display. Handles multiplexing, scrolling and supports loading
 * arbitrary animations.
 */
class Display {
	private:
		animation_t *current_anim;
		uint8_t need_update;
		uint8_t active_col;
		uint8_t disp_buf[8];
		uint8_t str_pos;
		uint8_t str_chunk;
		int8_t char_pos;

		enum AnimationStatus : uint8_t {
			RUNNING,
			SCROLL_BACK,
			PAUSED
		};

		AnimationStatus status;

	public:
		Display();

		/**
		 * Enable the display driver.
		 * Configures ports B and D as output and enables the display
		 * timer and interrupt.
		 */
		void enable(void);

		/**
		 * Disable the display driver.
		 * Turns off both the display itself and the display timer.
		 */
		void disable(void);

		/**
		 * Draws a single display column. Called every 256 microseconds
		 * by the timer interrupt (TIMER0_OVF_vect), resulting in
		 * a display refresh rate of ~500Hz (one refresh per 2048µs)
		 */
		void multiplex(void);

		/**
		 * Reset display and animation state. Fills the screen with "black"
		 * (that is, no active pixels) and sets the animation offset to zero.
		 */
		void reset(void);

		/**
		 * Update display content.
		 * Checks current_anim->speed and current_anim->type and scrolls
		 * the text / advances a frame when appropriate. Does nothing
		 * otherwise.
		 */
		void update(void);

		/**
		 * Set the active animation to be shown on the display. Automatically
		 * calls reset().
		 *
		 * @param anim active animation. Note that the data is not copied,
		 *        so anim has to be kept in memory until a new one is loaded
		 */
		void show(animation_t *anim);
};

extern Display display;