aboutsummaryrefslogtreecommitdiffstats
path: root/src/globals.c
blob: 9d0a5bb5d6b9c8a2ebe0db5829ab7cfdf5ba1400 (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//
// Globals.
//

static int step_counter = 0;
int trig_selection_loc = 0;
int param_selection_loc = 0;
int channel_selection_loc = 0;
int pattern_selection_loc = 0;
int right_col_selection_loc = 0;
int play_status = 0;
int current_pattern = 0;
int next_pattern = 0;
int current_bank = 0;
int next_bank = 0;
u32 last_trig_loc = 0;
u32 last_channel_loc = 0;
u32 last_pattern_loc = 0;
u32 last_right_col_loc = 0;
u32 last_step_counter = 0;
bool clear_screen = true;

//
// Color indexes.
//

#define COL_BG    0
#define COL_FG    1
#define COL_ACC_0 2
#define COL_ACC_1 3
#define COL_ACC_2 4
#define COL_OFF   5

#define CHAN_W 18
#define CHAN_H 8
#define CHAN_START_X 28
#define CHAN_START_Y 100
#define CHAN_OFFSET_Y 15

#define TRIG_W 15
#define TRIG_H 22
#define TRIG_START_X 55
#define TRIG_START_Y 100
#define TRIG_OFFSET_X (TRIG_W + 3)
#define TRIG_OFFSET_Y (TRIG_H + 8)

#define PIANO_W 170
#define PIANO_H 12
#define PIANO_BLACK_H 10
#define PIANO_START_X 27
#define PIANO_START_Y 80
#define PIANO_NOTE_W 2

#define NOTIF_W 170
#define NOTIF_H 10
#define NOTIF_START_X 27
#define NOTIF_START_Y 12

#define PARAMS_W 166
#define PARAMS_H 56
#define PARAMS_START_X 29
#define PARAMS_START_Y 20
#define PARAMS_BOX_W 30
#define PARAMS_BOX_H 24
#define PARAMS_BOX_OFFSET_X (PARAMS_BOX_W + 4)
#define PARAMS_BOX_OFFSET_Y (PARAMS_BOX_H + 4)

#define R_SIDEBAR_X ((TRIG_START_X) + (TRIG_OFFSET_X) * 8 + 8)

#define PAT_START_X 5
#define PAT_START_Y 16
#define PAT_W 14
#define PAT_H 10
#define PAT_OFFSET_Y 18

#define R_COL_W 30
#define BPM_START_X (R_SIDEBAR_X - 2)
#define BPM_START_Y (TRIG_START_Y + 8)
#define BPM_H 15

#define SCALE_START_X (R_SIDEBAR_X - 2)
#define SCALE_START_Y (PIANO_START_Y)
#define SCALE_H 15

#define SETTINGS_START_X (R_SIDEBAR_X - 4)
#define SETTINGS_START_Y (TRIG_START_Y + 30)
#define PLAY_START_X (R_SIDEBAR_X - 2)
#define PLAY_START_Y (TRIG_START_Y + 44)
#define STOP_START_X (R_SIDEBAR_X + 14)
#define STOP_START_Y (TRIG_START_Y + 44)
#define PLAY_STOP_W (12)
#define PLAY_STOP_H (8)

#define BANK_START_X (R_SIDEBAR_X + 5)
#define BANK_START_Y (PAT_START_Y)
#define BANK_W 12
#define BANK_H 10

#define PAT_TRIG_W 14
#define PAT_TRIG_H 14
#define PAT_TRIG_START_X 32
#define PAT_TRIG_START_Y 37
#define PAT_TRIG_OFFSET_X (PAT_TRIG_W + 7)
#define PAT_TRIG_OFFSET_Y (PAT_TRIG_H + 8)

#define SEQ_N_CHANNELS 4

enum RIGHT_COL_LOC {
    R_COL_BANK_A   = 0,
    R_COL_BANK_B   = 1,
    R_COL_BANK_C   = 2,
    R_COL_BANK_D   = 3,
    R_COL_BANK_E   = 4,
    R_COL_BANK_F   = 5,
    R_COL_SCALE    = 6,
    R_COL_BPM      = 7,
    R_COL_SETTINGS = 8,
    R_COL_PLAY     = 9,
    R_COL_STOP     = 10,
    R_COL_END,
};

// Input handling works using a FSM. The input handler is switched to whichever
// function controls each section. For example, channel selection or trigger
// selection.
typedef void (*InputHandler)(void);

InputHandler input_handler;

void handle_trigger_selection(void);
void handle_channel_selection(void);
void handle_pattern_selection(void);
void handle_param_selection_sq1(void);
void handle_param_selection_sq2(void);
void handle_param_selection_wave(void);
void handle_param_selection_noise(void);
void handle_right_col_selection(void);
void handle_param_selection_ch1(void);
void handle_param_selection_ch2(void);
void handle_param_selection_ch3(void);
void handle_param_selection_ch4(void);
void handle_pattern_chain(void);

typedef enum Scene {
    SCENE_SEQUENCER = 0,
    SCENE_SETTINGS,
} Scene;

static Scene scene = SCENE_SEQUENCER;
static Scene next_scene = SCENE_SEQUENCER;

typedef struct Notification {
    // We can only fit 31 characters on the notification bar at the moment.
    // Leaving an extra character for \0.
    char msg[32];
    s16 time;
} Notification;

static Notification notif = {0};

#define NOTIF_TIME (80 + 32)

#define MAX_CHAIN 16
typedef struct Chain {
    u8 chain[MAX_CHAIN];
    u8 active[MAX_CHAIN];
    u8 len;
    u8 current;
    u8 playing;
    u8 enabled;
} Chain;

typedef enum ChainButtons {
    CHAIN_BTN_ENABLE = 16,
    CHAIN_BTN_CLEAR = 17,
    CHAIN_BTN_RANDOM = 18,
} ChainButtons;

static Chain chain = {0};

typedef enum Prob {
    PROB_FOUR_FOUR,
    PROB_THREE_FOUR,
    PROB_TWO_FOUR,
    PROB_ONE_FOUR,
    PROB_THREE_THREE,
    PROB_TWO_THREE,
    PROB_ONE_THREE,
    PROB_TWO_TWO,
    PROB_ONE_TWO,
    PROB_NOT_FIRST,
    PROB_FIRST,
    PROB_100,
    PROB_80,
    PROB_60,
    PROB_40,
    PROB_20,
    PROB_NUM,
} Prob;

bool redraw_pattern_buttons = true;
bool redraw_play_pause = true;
bool redraw_trigs = true;
bool redraw_channels = true;
bool redraw_bank_buttons = true;
bool redraw_params = true;
bool redraw_bpm = true;
bool redraw_scale = true;
bool update_bpm = false;
u8 bar_counter = 0;

typedef enum WaveEnv {
    WAV_ENV_START,
    WAV_ENV_ATTACK,
    WAV_ENV_DECAY,
    WAV_ENV_END,
    WAV_ENV_OFF,
} WaveEnv;

enum WAVES {
    WAVE_SIN,
    WAVE_SAW,
    WAVE_SQUARE,
    WAVE_MAX,
};

#define WAVE_SIZE 4
#define WAVE_VARS 4

typedef u32 Wave[WAVE_SIZE];

static WaveEnv wave_env = WAV_ENV_OFF;
static const Wave *wave_target;
static u32 wave_freq;
static int wave_env_ticks = 0;
static int wave_env_attack = 8;
static int wave_env_decay = 8;
static int wave_env_prog = 0;
static Wave current_wave[8] = {0};